我们知道我们可以配置log4j,通过它的属性/配置文件关闭特定位置的日志(在Java中的类或包)。以下是我的问题:
谢谢,
发布于 2010-02-09 07:31:33
是的,日志语句仍将被执行。这就是为什么首先检查日志级别是一个很好的模式:
if (log.isInfoEnabled()) {
log.info("My big long info string: " + someMessage);
}
这是为了避免在日志级别不支持String
语句时为info INFO
重新分配空间。
它不像#ifdef
- #ifdef
是编译器指令,而Log4J配置是在运行时处理的。
编辑:我讨厌因为无知而被降级,所以这里有一篇文章支持我的答案。
来自http://surguy.net/articles/removing-log-messages.xml
中的Log4J,如果您在调试级别记录消息,并且当前的附录被设置为只记录信息级别及以上的消息,那么消息将不会显示。调用日志方法本身的性能损失最小-几纳秒。但是,计算日志方法的参数可能需要更长的时间。例如:
Logger.debug(“大对象是"+largeObject.toString());
计算largeObject.toString()可能很慢,并且在调用记录器之前对其进行评估,因此记录器不能阻止对其进行计算,即使它不会被使用。
编辑2:来自log4j手册本身(http://logging.apache.org/log4j/1.2/manual.html):
用户应该知道以下性能问题。
关闭日志记录时,
然而,方法调用涉及到参数构造的“隐藏”成本。
例如,对于一些伐木猫,写作,
Logger.debug(“条目编号:”+i+“是”+String.valueOf(Entryi)“);
这将导致构造消息参数的成本,即将整数i和entryi转换为字符串,并连接中间字符串,而不管消息是否将被记录。这一参数建设成本可能相当高,这取决于所涉及的参数的大小。
为了避免参数的施工成本,写:
if(logger.isDebugEnabled() {logger.debug(“条目编号:”+i+“”是“+String.valueOf(Entryi)”);}
如果禁用调试,这将不会导致参数构造的成本。另一方面,如果记录器启用了调试,则评估是否启用记录器将花费两倍的成本:一次在debugEnabled中,一次在调试中。这是一个微不足道的开销,因为评估记录器所需的时间约为实际日志所需时间的1%。
发布于 2010-02-09 08:02:47
我运行了一个简单的基准测试。
for (int j = 0; j < 5; j++) {
long t1 = System.nanoTime() / 1000000;
int iterations = 1000000;
for (int i = 0; i < iterations; i++) {
int test = i % 10;
log.debug("Test " + i + " has value " + test);
}
long t2 = System.nanoTime() / 1000000;
log.info("elapsed time: " + (t2 - t1));
long t3 = System.nanoTime() / 1000000;
for (int i = 0; i < iterations; i++) {
int test = i % 10;
if (log.isDebugEnabled()) {
log.debug("Test " + i + " has value " + test);
}
}
long t4 = System.nanoTime() / 1000000;
log.info("elapsed time 2: " + (t4 - t3));
}
elapsed time: 539
elapsed time 2: 17
elapsed time: 450
elapsed time 2: 18
elapsed time: 454
elapsed time 2: 19
elapsed time: 454
elapsed time 2: 17
elapsed time: 450
elapsed time 2: 19
对于1.6.0_18,这让我感到惊讶,因为我以为内衬会阻止这件事。也许有转义分析的Java 7会。
但是,我仍然不会将调试语句包装在if子句中,除非时间的改进(半微秒级)变得重要了!
发布于 2010-02-09 07:41:52
https://stackoverflow.com/questions/2230180
复制相似问题