我建议在登录java时使用此语法:
if (logger.isLoggable(Log.FINE))
{
logger.fine("bla"+" bla"+" bla");
}
这样做的原因是为了避免参数字符串的冗余构造,因为日志记录级别低于“FINE”。 (在上面的例子中 - 5个冗余的字符串对象。(“bla”X3,“bla bla”和“bla bla bla”)。
我想听听其他人正在做些什么,或者你认为这是必要的。
谢谢!
答案 0 :(得分:6)
一些较新的日志记录框架允许您将参数指定为参数,如果没有日志记录,则不会评估它们。
我找到的例子是LogBack,它是Log4j的继承者。这是信息:http://www.infoq.com/news/2007/08/logback
这可以说是两全其美的。优雅的语法和良好的性能。
Log4j代码示例:
if( logger.isDebugEnabled() ) {
logger.debug( "User with account " +
user.getAccount() + " failed authentication; " +
"supplied crypted password " + user.crypt(password) +
" does not match." );
}
等效LogBack代码:
logger.debug( "User with account {} failed authentication; " +
"supplied crypted password {} does not match.",
user.getAccount(), user.crypt(password) );
这将延迟消息组装的成本,直到LOGBack确定是否将查看此消息。它不会延迟检索昂贵参数的成本,例如上例中的密码加密。
答案 1 :(得分:0)
字符串对象是不可变的,因此重复连接是一项昂贵的操作。它需要重复的内存分配,对象创建和迭代。考虑到更精细的日志级别的某些日志记录调用可以每分钟调用数千或数百万次,所以在您说明时可能会获得相当大的性能提升。但是,对于较小的应用程序,可能不值得额外的努力。
作为旁注:您可以通过使用如下的常量来保存更高的性能,这是非常关键的:
public static final boolean DEBUG = false;
如果现在将日志代码包装在if-block中,那么在产品模式下运行时,JVM将能够完全优化调试调用。这与你到达C #ifdef的距离很近。
if (Globals.DEBUG) {
// Logging call
}
答案 2 :(得分:0)
调试类型日志记录绝对必要。比首先检查日志级别要快10倍,而不是创建字符串然后扔掉它。
答案 3 :(得分:0)
这是一项改进(很好),但可以稍微改进一下。
在用作配置的全局对象中为每个日志记录级别(FINE等)设置最终标志,然后使用StringBuffer构建调试输出 - 您甚至可以同时将数字格式化为流。< / p>
public class MyAppConfig {
public final boolean FINE=true;
// ... other fields
}
public class MyApp {
void someFunction() {
...
int imagesProcessed;
imagesProcessed = processImages();
if (MyAppConfig.FINE) logger.fine(new StringBuffer(35).
append("Count of images processed: ").append(imagesProcessed).toString());
...
}
}
这里的字符串缓冲区设置为35个字符的“初始容量”。如果你知道要生成多少个字符,你可以为StringBuffer提供提示。