Java 如何使用更少的logger.isDebugEnabled()
在这里,我将为logger.debug()添加logger.isDebugEnabled()条件语句。 但有时循环中有许多logger.debug()。例如:Java 如何使用更少的logger.isDebugEnabled(),java,log4j,Java,Log4j,在这里,我将为logger.debug()添加logger.isDebugEnabled()条件语句。 但有时循环中有许多logger.debug()。例如: Logger log = Logger.getLogger(Test.class); for(int i = 0; i < 1000; i++) { ... log.debug("aaaaa"); ... for(int j = 0; i < 100; j++) { ...
Logger log = Logger.getLogger(Test.class);
for(int i = 0; i < 1000; i++) {
...
log.debug("aaaaa");
...
for(int j = 0; i < 100; j++) {
...
log.debug("bbbb");
}
}
Logger log=Logger.getLogger(Test.class);
对于(int i=0;i<1000;i++){
...
log.debug(“aaaaa”);
...
对于(int j=0;i<100;j++){
...
log.debug(“bbbb”);
}
}
如果我直接添加,如下所示:
for(int i = 0; i < 1000; i++) {
...
if(log.isDebugEnabled()) {
log.debug("aaaaa");
}
...
for(int j = 0; i < 100; j++) {
...
if(log.isDebugEnabled()) {
log.debug("bbbb");
}
}
}
boolean logging = log.isDebugEnabled();
if (logging) {
for (int i = 0; i < 1000; i++) {
// stuff
log.debug("Hi Mum!");
// more stuff
}
} else {
for (int i = 0; i < 1000; i++) {
// stuff
// more stuff
}
}
for(int i=0;i<1000;i++){
...
if(log.isDebugEnabled()){
log.debug(“aaaaa”);
}
...
对于(int j=0;i<100;j++){
...
if(log.isDebugEnabled()){
log.debug(“bbbb”);
}
}
}
因此,在循环中,它将多次使用if()。如果(logger.isDebugEnabled()),如何使用更少的内存?
有人有什么想法吗?
谢谢。使用。将
log.isDebugEnabled()
的值存储在局部变量中,如下所示:
// Calculate once and cache the answer
boolean areLogging = log.isDebugEnabled();
for (int i = 0; i < 1000; i++) {
...
if (areLogging) {
log.debug("aaaaa");
}
...
for (int j = 0; i < 100; j++) {
...
if (areLogging) {
log.debug("bbbb");
}
}
}
log.debug("Today is " + date);
//计算一次并缓存答案
布尔值areloging=log.isDebugEnabled();
对于(int i=0;i<1000;i++){
...
如果(正在记录){
log.debug(“aaaaa”);
}
...
对于(int j=0;i<100;j++){
...
如果(正在记录){
log.debug(“bbbb”);
}
}
}
已经指出使用slf4j。具体来说,您应该使用slf4j的“参数化消息”特性
发布的代码未演示使用中的实用程序。显然,“bbbb”将被视为一个字符串文字(因为编译器可以在运行时计算它的值并将其放入类的常量池中),当类被加载并汇集到内部字符串池中时,JVM将加载该字符串文字;显然,构建日志消息没有成本,而且log.isDebugEnabled()
调用是冗余的。因此,我将通过一个更具描述性的示例来说明参数化消息的使用,该示例演示了参数化消息的好处
for(int j = 0; i < 100; j++) {
...
if(log.isDebugEnabled()) { // this is required by log4j. Without this, on every iteration, a new String object will be created in the following statement.
log.debug("Loop counter is" + j); // This constructs a new String object only if DEBUG is enabled.
}
}
for(int j=0;i<100;j++){
...
如果(log.isDebugEnabled()){//这是log4j所必需的。如果没有这个,在每次迭代中,将在下面的语句中创建一个新的字符串对象。
log.debug(“循环计数器为”+j);//仅当启用了调试时,它才会构造一个新的字符串对象。
}
}
可简化为:
for(int j = 0; i < 100; j++) {
...
log.debug("Loop counter is {}", j); //There is no explicit call to log.isDebugEnabled() in this case. The log message will be created only if DEBUG is enabled.
}
for(int j=0;i<100;j++){
...
log.debug(“循环计数器为{}”,j);//在这种情况下,没有显式调用log.isDebugEnabled()。只有在启用调试时才会创建日志消息。
}
String literal循环计数器为{}
再次汇集在String intern池中,但在运行时,值为循环计数器为0
,循环计数器为1
等的String对象将由slf4j创建,仅当启用调试级别时
我关心的是循环中的if()是否会影响性能
考虑以下代码:
boolean logging = log.isDebugEnabled();
for (int i = 0; i < 1000; i++) {
// stuff
if (logging) {
log.debug("Hi Mum!");
}
// more stuff
}
然而,在我看来,治愈比疾病更糟糕
@维内特的观点也很重要。在实践中,这样做的代价高昂:
// Calculate once and cache the answer
boolean areLogging = log.isDebugEnabled();
for (int i = 0; i < 1000; i++) {
...
if (areLogging) {
log.debug("aaaaa");
}
...
for (int j = 0; i < 100; j++) {
...
if (areLogging) {
log.debug("bbbb");
}
}
}
log.debug("Today is " + date);
字符串连接表达式的计算与实际日志记录级别无关。除了
if
测试之外,还有其他方法可以避免这种开销。。。尽管它们比缓存标志上的if
测试更昂贵 如果我使用slf4j,则不需要logger.isDebugEnable(),那么效果与logger.debug()相同?或者与if(logger.isDebugEnable()){logger.debug()}相同?两者都没有(但接近后者),请查看它是否正常。但是,if(areloging)也会使用很多次。我关心的是循环中的if()是否会影响性能?谢谢。但是在这个大型项目中,有数千个文件都使用log4j,我要修改的只是一个模块下的几个文件。所以,我想我现在不会使用slf4j。这是另一个问题。您可以缓存log.isDebugEnabled
返回值,因为这样更直观。如果您的Logger
对象是每类静态变量,则可以用类似的方式初始化此标志。但是,如果缓存该值的力度过大,也可能会失去对记录器执行动态配置的能力。谢谢。显然,存在一些字符串连接。+1是关于计算部分的提示,而不考虑日志级别。