Java 如何使用更少的logger.isDebugEnabled()

Java 如何使用更少的logger.isDebugEnabled(),java,log4j,Java,Log4j,在这里,我将为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++) { ...

在这里,我将为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");
    }
}
Logger log=Logger.getLogger(Test.class);
对于(int i=0;i<1000;i++){
...
log.debug(“aaaaa”);
...
对于(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");
         }
    }
}
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
    }
} 
for(int i=0;i<1000;i++){
...
if(log.isDebugEnabled()){
log.debug(“aaaaa”);
}
...
对于(int j=0;i<100;j++){
...
if(log.isDebugEnabled()){
log.debug(“bbbb”);
}
}
}
因此,在循环中,它将多次使用if()。如果(logger.isDebugEnabled()),如何使用更少的内存?
有人有什么想法吗?

谢谢。

使用。

log.isDebugEnabled()
的值存储在局部变量中,如下所示:

// 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");
        }
    }
}
log.debug("Today is " + date);
//计算一次并缓存答案
布尔值areloging=log.isDebugEnabled();
对于(int i=0;i<1000;i++){
...
如果(正在记录){
log.debug(“aaaaa”);
}
...
对于(int j=0;i<100;j++){
...
如果(正在记录){
log.debug(“bbbb”);
}
}
}

已经指出使用slf4j。具体来说,您应该使用slf4j的“参数化消息”特性

发布的代码未演示使用中的实用程序。显然,“bbbb”将被视为一个字符串文字(因为编译器可以在运行时计算它的值并将其放入类的常量池中),当类被加载并汇集到内部字符串池中时,JVM将加载该字符串文字;显然,构建日志消息没有成本,而且
log.isDebugEnabled()
调用是冗余的。因此,我将通过一个更具描述性的示例来说明参数化消息的使用,该示例演示了参数化消息的好处

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.isDebugEnabled()){//这是log4j所必需的。如果没有这个,在每次迭代中,将在下面的语句中创建一个新的字符串对象。
log.debug(“循环计数器为”+j);//仅当启用了调试时,它才会构造一个新的字符串对象。
}
}
可简化为:

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.
}
for(int j=0;i<100;j++){
...
log.debug(“循环计数器为{}”,j);//在这种情况下,没有显式调用log.isDebugEnabled()。只有在启用调试时才会创建日志消息。
}
String literal
循环计数器为{}
再次汇集在String intern池中,但在运行时,值为
循环计数器为0
循环计数器为1
等的String对象将由slf4j创建,仅当启用调试级别时

我关心的是循环中的if()是否会影响性能

考虑以下代码:

    boolean logging = log.isDebugEnabled();

    for (int i = 0; i < 1000; i++) {
        // stuff
        if (logging) { 
            log.debug("Hi Mum!");
        }
        // more stuff
    }
然而,在我看来,治愈比疾病更糟糕


@维内特的观点也很重要。在实践中,这样做的代价高昂:

// 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");
        }
    }
}
log.debug("Today is " + date);

字符串连接表达式的计算与实际日志记录级别无关。除了
if
测试之外,还有其他方法可以避免这种开销。。。尽管它们比缓存标志上的
if
测试更昂贵

如果我使用slf4j,则不需要logger.isDebugEnable(),那么效果与logger.debug()相同?或者与if(logger.isDebugEnable()){logger.debug()}相同?两者都没有(但接近后者),请查看它是否正常。但是,if(areloging)也会使用很多次。我关心的是循环中的if()是否会影响性能?谢谢。但是在这个大型项目中,有数千个文件都使用log4j,我要修改的只是一个模块下的几个文件。所以,我想我现在不会使用slf4j。这是另一个问题。您可以缓存
log.isDebugEnabled
返回值,因为这样更直观。如果您的
Logger
对象是每类静态变量,则可以用类似的方式初始化此标志。但是,如果缓存该值的力度过大,也可能会失去对记录器执行动态配置的能力。谢谢。显然,存在一些字符串连接。+1是关于计算部分的提示,而不考虑日志级别。