由IsDebugEnabled想到的

长期以来我们都会在各种代码里面见到这样的Log代码

if(logger.isDebugEnabled()){
logger.debug("this is a log");
}

昨天@WW同学在讨论组里面发言问到这个问题,我一直以来只知道这样做比单纯的
logger.debug(“this is a log”);
代码要高效(其实这也是不一定的)至于为什么高效却一直不清楚,后来@GF一点拨
原来是字符拼接的原因(可能还有其他原因)。

那么这个问题就到了String, StringBuilder问题上了,从各种渠道我们了解到在做长的字符拼接时
我们一定要选用StringBuilder来做因为,String是immutable的也就是说如果用String去拼接那么每次
拼接都要产生一个新的String对象,这样不仅浪费了空间甚至还损失了性能。

但是我还是想知道这两者的性能到底有多大于是我做了如下的实验
Demo1:

for (int i = 0; i < 1000000; i++) {
     String a = "abc" + "bcd";
}

Demo2:

for
 (int i = 0; i < 1000000; i++) {
     String a = New StringBuilder("abc").append("bcd").toString();
}

结果发现Demo1要远远快于Demo2,当时我惊讶了但是仔细一想这其实是编译器优化的结果Demo1中其实for中的语句等价于
String a = “abcbcd”;所以他当然要比下面的Demo2快

稍作修改
Demo1:

for(int i = 0; i < 1000000; i++) {
     String a = "abc" + i;
}

Demo2:

for(int i = 0; i < 1000000; i++) {
     String a = New StringBuilder("abc").append(i).toString();
}

数据:
比较
从上面这组数据来看的话相差不大的,因为同样Demo1的语句会进行Demo2中样式的优化

那么什么情况下字符串拼接的劣势会暴露无遗了
Demo1

String a = "abc";
for(int i = 0; i < 1000000; i++) {
     a += "a";
}

Demo2

StringBuilder a = new StringBuilder("abc");
for(int i = 0; i < 1000000; i++) {
     a.append("a");
}

这时候Demo2比Demo1快了多了去了,给一个数据:拼接一个65536长度的字符串(char by char) 话费大概 22 秒在 AMD64 X2 4200+上

编译器的优化原理我还不太懂,什么时候可以优化什么时候不可以优化还不太知道而且各个jdk厂商不一样也不能一概而论

总结:
1)什么时候用StringBuilder
当有许多字符串拼接的时候使用(特别是在log中打印重写了toString的对象,toString里面用StringBuilder会比较好)
2)短的字符拼接为了代码整洁还是采用a + b + c这种形式
3)虽然这是个小问题,但是挖掘小问题背后的道理才是进步的持续动力!!!

Meta

Published: Feb. 16, 2012 Author: ivan Comments:   Word Count: 131
Bookmark and Share

Next: :() { :|:& }; :

Tags

isdebugenabled java log

Attachments

Comments powered by Disqus