1. 问题背景
我们在源码或其他日常代码中经常发现在执行logger.debug()方法前还会判断一下是否是debug级别,这个判断步骤是否多余??
String prodStr=environment.getProperty("knife4j.production");
if (logger.isDebugEnabled()){
logger.debug("swagger.production:{}",prodStr);
}
2. 问题分析
- 先看看isDebugEnabled源码
public boolean isDebugEnabled() {
if(repository.isDisabled( Level.DEBUG_INT))
return false;
return Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel());
}
- 再看看debug()源码
public void debug(Object message) {
if(repository.isDisabled(Level.DEBUG_INT))
return;
if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
forcedLog(FQCN, Level.DEBUG, message, null);
}
}
对比后我们可以发现,debug()方法中其实重复了isDebugEnabled()的代码,那么为什么连源码中都会出现这种问题呢?
抱着大神不可能犯这么简单的错误的基本方针…继续搜索着答案…
细想一下,debug()方法中是有参数的,如果要调用debug方法,需要先传参数,而参数分为两种,一种是直接输出一段“死文字”,还有一种是一段“活文字”,即调用debug()方法之前是否还要执行完另一个耗时的操作,如下
- 死文字
logger.debug("the weather is windy!");
- 活文字
logger.debug("the total money is {}" ,getTotalMoney());
在调用debug()方法之前会先执行getTotalMoney方法,如果在访问很频繁的情况下,多调用这么耗费的一点点时间和性能就会变得很明显;
也许有人会说,debug模式哪有那么多访问量?
我想说,并不是只有debug模式下才会执行 logger.debug() 方法,普通的info模式,它也是会执行 debug() 方法;
根据getTotalMoney()方法调用次数,我们具体分析一下:
1.调用一次(且只有日志中需要调用一次)
if (logger.isDebugEnabled()){
logger.debug("the total money is:{}",getTotalMoney());
}
这种情况我认为加上isDebugEnabled()方法更优
2.调用多次(不只日志中需要调用一次)
float totalMoney = getTotalMoney();
logger.debug("the total money is:{}",totalMoney );
//后续有继续使用totalMoney这个变量的逻辑
//如果后续没有的话,也没有必要执行方法后再复制给一个变量,仍然属于上述的调用一次的情况
调用getTotalMoney()并赋值给一个变量totalMoney,供后面调用,
此时,
私以为,
无需加上isDebugEnabled()方法会更优,因为此时输出的表面是“活文字”,实则“死文字”;
3. 结论
是否需要多加一个isDebugEnabled() ,取决于调用debug()方法的是“死文字”还是|“活文字”,前者无需再多加一层判断,后者极有可能多加一层判断会更优!
如果个人有什么理解不对的地方,欢迎留言指正~