很多人习惯把线程安全的StringBuffer用做局部变量,依赖于JIT,不比StringBuilder慢。
StringBuffer虽然加了synchronized,做局部变量时,锁住的只是线程局部变量,没有锁竞争
类似于synchronized(new Object()),是没有意义的。
JVM运行一会就发现这个无意义的锁,可以被清除掉,就做“锁省略”优化.
再执行,无锁的StringBuffer性能就跟StringBuilder差不多了.
这个简单的近乎没有意义的测试(或者因为如此吧,被投了几个“新手贴”, 哈。。。),测的却是表面上看不到的优化
参考
JVM优化之逃逸分析(Escape Analysis) http://www.iteye.com/topic/473355
Mustang 中的同步优化 http://www.ibm.com/developerworks/cn/java/j-jtp10185/
再谈 Urban 性能传言 http://www.ibm.com/developerworks/cn/java/j-jtp09275.html
public void test() throws Exception {
int total = 11000000;
for (int x = 0; x < 100; x++) {
StringBuffer sb1 = new StringBuffer(total);
long start = System.currentTimeMillis();
for (int i = 0; i < total; i++) {
sb1.append(1);
}
long sb1Time = System.currentTimeMillis() - start;
StringBuilder sb2 = new StringBuilder(total);
start = System.currentTimeMillis();
for (int i = 0; i < total; i++) {
sb2.append(1);
}
System.out.println(sb1Time + " " + (System.currentTimeMillis() - start));
}
}
执行结果
688 203
688 219
688 219
703 203
687 203
218 218
218 218
218 203
219 219
219 219
219 203
.......
可以看到,前几次调用,StringBuffer比StringBuilder慢的多,执行几次之后,两者已经接近