Java 是否需要进行 if(log.isDebugEnabled()) { ... } 检查?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6504407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a need to do a if(log.isDebugEnabled()) { ... } check?
提问by Oh Chin Boon
is there a need to do an explicit if(log.isDebugEnabled()) { ... } check?
是否需要进行明确的 if(log.isDebugEnabled()) { ... } 检查?
I mean i have seen some post mentioning that log.debug("something") does an implicit call to see if debug mode logging has been enabled, before it does the logging. Am i missing something or is there an intermediary step that is to be performed before this is used?
我的意思是我看到一些帖子提到 log.debug("something") 在进行日志记录之前会进行隐式调用以查看是否已启用调试模式日志记录。我是否遗漏了某些东西,或者在使用此之前是否需要执行中间步骤?
Thanks!
谢谢!
log.debug("ResultSet rs is retrieved from OracleTypes");
vs
对比
if(log.isDebugEnabled()){
log.debug("ResultSet rs is retrieved from OracleTypes");
}
Edit: Did a write up on this: http://java.sg/whether-to-do-a-isdebugenabled-checking-before-printing-out-your-log-statement/
编辑:对此写了一篇文章:http: //java.sg/whether-to-do-a-isdebugenabled-checking-before-printing-out-your-log-statement/
采纳答案by Filipe Palrinhas
The statement:
该声明:
if(log.isDebugEnabled()){
Is used just for performance reasons. It's use is optional since it is called by the log method internally.
仅用于性能原因。它的使用是可选的,因为它在内部由 log 方法调用。
But now you ask if this check is made internally, so why should I use it? It's very simple: if you log something as simple as this:
但是现在你问这个检查是否是内部进行的,那我为什么要使用它?这很简单:如果你记录一些像这样简单的东西:
log.debug("ResultSet rs is retrieved from OracleTypes");
Then you don't need to do any check. If you compose a string to log using the append operator (+) like this:
那么你不需要做任何检查。如果您使用附加运算符 (+) 编写要记录的字符串,如下所示:
log.debug("[" + System.getTimeInMillis() + "] ResultSet rs is retrieved from OracleTypes");
In this case you should check if the log is enabled or not, because if it isn't, even if the log is not made, the string composition is. And I must remind you that the use of operator "+" to concatenate strings is very inefficient.
在这种情况下,您应该检查是否启用了日志,因为如果不是,即使没有创建日志,字符串组合也是。而且我必须提醒您,使用运算符“+”来连接字符串是非常低效的。
回答by wjans
The reason this is done is for performance reasons. If checking this first, the log.debug(...
statement shouldn't be evaluated.
这样做的原因是出于性能原因。如果首先检查这一点,则log.debug(...
不应评估该语句。
It is indeed functionally the same.
在功能上确实是一样的。
回答by Bohemian
The recent versions of Logger streamline this, so there's not much difference.
Logger 的最新版本对此进行了简化,因此没有太大区别。
The biggest difference is you don't have to create the stuff to log - sometimes there's a lot of string addition going on.
最大的区别是您不必创建要记录的内容 - 有时会进行很多字符串添加。
回答by yngwietiger
I know this is old, but for anyone just finding this...
我知道这很旧,但对于任何发现这个的人......
If you use SLF4J, you can avoid the isDebugEnabled() call, by using messaging formatting.
如果您使用 SLF4J,您可以通过使用消息格式来避免 isDebugEnabled() 调用。
For example, instead of:
例如,而不是:
Object entry = new SomeObject();
logger.debug("The entry is " + entry + ".");
Use:
用:
Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);
The message formatting will not be evaluated unless debug is enabled.
除非启用调试,否则不会评估消息格式。
So, for simple cases, you could avoid isDebugEnabled().
因此,对于简单的情况,您可以避免使用 isDebugEnabled()。
But in a case where building one of the parameters might be expensive, you would still want to use isDebugEnabled() (even with SLF4J).
但是在构建其中一个参数可能很昂贵的情况下,您仍然希望使用 isDebugEnabled()(即使使用 SLF4J)。
For example:
例如:
if (logger.isDebugEnabled()) {
logger.debug("Here is the SQL: {}", sqlWrapper.buildSQL()); // assume buildSQL() is an expensive operation
}
In that case, you don't want to evaluate buildSQL() unless debug is actually enabled.
在这种情况下,除非实际启用调试,否则您不想评估 buildSQL()。
With SLF4J, there's some debate over using it always vs using it selectively. It really boils down to personal preference. You may want to use everywhere, to guard against another developer (unknowingly) changing your log message to something more complex/expensive in the future.
对于 SLF4J,对于始终使用它还是有选择地使用它存在一些争论。这真的归结为个人喜好。您可能希望在任何地方使用,以防止其他开发人员(在不知不觉中)将来将您的日志消息更改为更复杂/更昂贵的内容。
回答by Ashraff Ali Wahab
I checked with the below code by performing the check in my code vs not performing the check. Interestingly if the check is performed in our code for a 4 log statement executed a million times it takes 400 ms extra. I am using SLF4J 1.6.6. If you can afford to loose 400 ms per million request ,you don't need the check.
我通过在我的代码中执行检查与不执行检查来检查以下代码。有趣的是,如果在我们的代码中对执行一百万次的 4 条日志语句执行检查,则需要额外花费 400 毫秒。我正在使用 SLF4J 1.6.6。如果您能负担得起每百万个请求 400 毫秒的时间,您就不需要检查。
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
if (logger.isTraceEnabled()) {
logger.trace(request.getUserID());
logger.trace(request.getEntitlementResource().getResourceString());
logger.trace(request.getEntitlementResource().getActionString());
logger.trace(request.getContextMap());
}
}
long endTime = System.currentTimeMillis();
logger.fatal("With Check Enabled : " + (endTime - startTime) + " ms");
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
logger.trace(request.getUserID());
logger.trace(request.getEntitlementResource().getResourceString());
logger.trace(request.getEntitlementResource().getActionString());
logger.trace(request.getContextMap());
}
endTime = System.currentTimeMillis();
logger.fatal("With Check Disabled : " + (endTime - startTime) + " ms");
---OUTPUT---
- -输出 - -
*2016-01-07 10:49:11,501 ERROR [:http-bio-8080-exec-3] [com.citi.cmb.entitlement.service.EntitlementServiceImpl][]- With Check Enabled : 661 ms
*2016-01-07 10:49:11,501 错误 [:http-bio-8080-exec-3] [com.citi.cmb.entitlement.service.EntitlementServiceImpl][]- 启用检查:661 毫秒
2016-01-07 10:49:57,141 ERROR [:http-bio-8080-exec-3] [com.citi.cmb.entitlement.service.EntitlementServiceImpl][]- With Check Disabled : 1043 ms
2016-01-07 10:49:57,141 错误 [:http-bio-8080-exec-3] [com.citi.cmb.entitlement.service.EntitlementServiceImpl][]- 禁用检查:1043 毫秒