在像C / C ++ / Objective-C的语言中是很常见使用预处理宏定义,甚至没有编译为二进制代码发布,从而导致性能没有记录机制。 沿着线的东西:
#ifdef DEBUG
printf("some event we want to log\n");
#endif
现在,我知道有一个在斯卡拉没有预处理。 所以我的问题是:什么是实现一种机制,以记录用于调试程序活动的最佳途径,而影响性能,当它关闭的最少?
在像C / C ++ / Objective-C的语言中是很常见使用预处理宏定义,甚至没有编译为二进制代码发布,从而导致性能没有记录机制。 沿着线的东西:
#ifdef DEBUG
printf("some event we want to log\n");
#endif
现在,我知道有一个在斯卡拉没有预处理。 所以我的问题是:什么是实现一种机制,以记录用于调试程序活动的最佳途径,而影响性能,当它关闭的最少?
您可以使用scala.annotation.elidable
用于该调用可能会在生成的代码被去除方法的注释。
行为是通过传递-Xelide,下面scalac影响。 方法标记elidable将从生成的代码如果给注释的优先级比所述命令行参数下被省略。 例子:
目前的做法(在斯卡拉2.9.x或更早)是使用一个thunk类型(例如见斯卡拉简单的日志门面SLFS ):
def log(x: =>Any) = if (logging) println(x)
// later in code
log("var1: " + myVar1)
这通常比实际构建的字符串,因为如果字符串创建(及任何后续活动)只是做更便宜的logging
是真实的。 但是,它仍然招致封创建为形实转换的成本x
以上。
然而,从斯卡拉2.10.x起,有包含在标准发布(见实验宏实现这个页面 ,或SIP )。 宏系统将允许你写日志调用它几乎不占用运行成本(比其他logging
变量检查) -它们允许你在一行上通话log
,让这样的:
log("var1: " + myVar1)
变为:
if (logging) log("var1: " + myVar1)
请注意,在这种情况下,没有为建立封闭log
,以及日志消息字符串只计算,如果logging
是真实的-成本只有当检查。
Log4J的是一种常见的JVM日志框架。 它是专门为具有最小性能的影响:
在AMD的毒龙主频为800Mhz的运行JDK 1.3.1,它的成本约5纳秒,以确定是否记录表应当记录与否。 实际记录也是相当快的,从使用SimpleLayout,使用TTCCLayout 37微秒21微秒。 在的PatternLayout的性能几乎是专用的布局一样好,但它是灵活得多。
所以,当你拨打电话,如:
LOG.debug("something here")
该框架将首先检查“调试”启用日志记录。 这种检查非常快。 如果日志被禁用,则它不会做任何更多的工作。
然而有一个陷阱。 如果你写
LOG.debug(expensiveOperation())
然后进行昂贵的操作之前,框架不会做具备调试功能的检查。 纠正这种情况的办法是说:
if(LOG.isDebugEnabled) LOG.debug(expensiveOperation())