如何减少使用logger.isDebugEnabled

问题描述

| 在这里,我将为logger.debug()添加logger.isDebugEnabled()条件语句。 但是有时候有很多logger.debug()循环。例如:
Logger log = Logger.getLogger(Test.class);

for(int i = 0; i < 1000; i++) {
    ...
    log.debug(\"aaaaa\");
    ...
    for(int j = 0; i < 100; j++) {
        ...
        log.debug(\"bbbb\");
    }
}
如果我直接添加它,如下所示:
for(int i = 0; i < 1000; i++) {
    ...
    if(log.isDebugEnabled()) {
        log.debug(\"aaaaa\");
    }
    ...
    for(int j = 0; i < 100; j++) {
        ...
        if(log.isDebugEnabled()) {
            log.debug(\"bbbb\");
         }
    }
}
因此,在循环中,它将多次if()。如果(logger.isDebugEnabled())我怎么用呢? 有人知道吗? 谢谢。     

解决方法

           我在乎的是,if()循环是否会影响性能? 考虑以下代码:
    boolean logging = log.isDebugEnabled();

    for (int i = 0; i < 1000; i++) {
        // stuff
        if (logging) { 
            log.debug(\"Hi Mum!\");
        }
        // more stuff
    }
“ 3”测试的成本可能只有2条指令,这取决于JIT编译器的寄存器分配如何完成。除非您进行大量的日志记录,否则这很可能无关紧要。 但是,如果这2到4条指令的性能影响确实很重要,则可以考虑: 完全取消对ѭ4的呼叫, 使它取决于编译时间常数(以便优化程序可以修剪代码),或者 使测试脱离循环;例如重组代码如下:
boolean logging = log.isDebugEnabled();

if (logging) {
    for (int i = 0; i < 1000; i++) {
        // stuff
        log.debug(\"Hi Mum!\");
        // more stuff
    }
} else {
    for (int i = 0; i < 1000; i++) {
        // stuff
        // more stuff
    }
} 
但是,IMO认为,治愈方法要比疾病要差。 @Vineet的观点也很重要。在实践中,类似这样的昂贵部分:
log.debug(\"Today is \" + date);
是无论实际的日志记录级别如何,都将评估String串联表达式。除了
if
测试之外,还有其他方法可以避免这种开销……尽管它们比对已缓存标志进行
if
测试要昂贵。     ,        使用slf4j。     ,        将ѭ9的值存储在本地变量中,如下所示:
// Calculate once and cache the answer
boolean areLogging = log.isDebugEnabled();

for (int i = 0; i < 1000; i++) {
    ...
    if (areLogging) { 
        log.debug(\"aaaaa\");
    }
    ...
    for (int j = 0; i < 100; j++) {
        ...
        if (areLogging) {
            log.debug(\"bbbb\");
        }
    }
}
    ,        已经指出了使用slf4j。具体来说,您应该使用slf4j的“参数化消息”功能。 所发布的代码未演示使用参数化消息的实用程序。显然,\“ bbbb \”将被视为String常量(因为编译器可以在运行时计算其值并将其放在类的常量池中),该常量将在加载类时由JVM加载并存储在内部字符串池中;构造日志消息显然没有任何成本,并且“ 9”调用是多余的。因此,我将通过一个更具描述性的示例来说明参数化消息的用法,以说明其优点
for(int j = 0; i < 100; j++) {
    ...
    if(log.isDebugEnabled()) { // this is required by log4j. Without this,on every iteration,a new String object will be created in the following statement.
        log.debug(\"Loop counter is\" + j); // This constructs a new String object only if DEBUG is enabled.
    }
}
可以简化为:
for(int j = 0; i < 100; j++) {
    ...
    log.debug(\"Loop counter is {}\",j); //There is no explicit call to log.isDebugEnabled() in this case. The log message will be created only if DEBUG is enabled.
}
字符串文字“ 14”再次存储在“字符串”内部存储池中,但是在运行时,只有启用了DEBUG级别时,slf4j才会创建具有值“ 15”,“ 16”等的String对象。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...