我们目前正在为医疗档案开发基于Scala和Akka Cluster的产品。在代码中有很多

if(logger.isDebugEnabled()) {
    logger.debug(expensiveFunction())
}

在我们以前的带有标准SQL / JPA,阻塞I / O和大量线程的代码中,这种构造或多或少是免费的。但是,在当今反应式编程时代,CPU高速缓存同步以及内存屏障和锁定被认为是昂贵的,应避免使用。 Logback isDebugEnabled()是否导致 Volatile 访问并因此导致内存障碍。如果是这样,是否有很多logger.isDebugEnabled()成为潜在的性能杀手?

关于CPU高速缓存同步和内存障碍的主题非常出色:
http://mechanical-sympathy.blogspot.se/2013/02/cpu-cache-flushing-fallacy.html

最佳答案

查看登录代码,在isDebugEnabled()内部没有访问任何锁或挥发。

但是,对于真正紧密的循环,我建议这样做:

boolean isDebugEnabled = log.isDebugEnabled();

while(cond) {
    if (isDebugEnabled) {
        log.debug(...);
    }
    doStuff();
}

如果在一个紧密的循环中调用了您的逻辑,但是该循环在另一个类中,则将isDebugEnabled设置为最终成员变量,然后在构造函数中对其进行初始化。由于热点将看到“if(false)”并仅删除代码,因此这可能会带来出色的性能。唯一的缺点是您不能即时更改日志级别,但是在大多数系统中这并不是什么大问题。

08-26 17:08