论坛首页 Java企业应用论坛

由StringBuffer和StringBuilder感受JVM运行时编译优化(just in time)

浏览 8116 次
精华帖 (0) :: 良好帖 (4) :: 新手帖 (16) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-05-12   最后修改:2010-05-14

很多人习惯把线程安全的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慢的多,执行几次之后,两者已经接近

 

 

   发表时间:2010-05-13  
局部变量我一般都用StringBuilder.
0 请登录后投票
   发表时间:2010-05-13  
x_root 写道
局部变量我一般都用StringBuilder.

      jvm 可以自动释放锁的啊?
0 请登录后投票
   发表时间:2010-05-13  
只能说jvm确实牛。
0 请登录后投票
   发表时间:2010-05-13  
这个结论比较肤浅,像是猜的
0 请登录后投票
   发表时间:2010-05-13   最后修改:2010-05-13
明显是猜的, 这也能叫分析
0 请登录后投票
   发表时间:2010-05-13  
liu78778 写道
明显是猜的, 这也能叫分析


请了解一下JIT再来看是不是猜的吧
0 请登录后投票
   发表时间:2010-05-13  
理论上虽然快...但是,一般都是用StringBuffer ......
1 请登录后投票
   发表时间:2010-05-13  
谢谢lz吧  又受教了。。 确实一般都用在 方法里 (也就是做局部变量)方法区本来就不是线程安全的 但非要用StringBuffer 这个线程安全的东西 也没吗用。。。 行以后改用StringBuilder
0 请登录后投票
   发表时间:2010-05-13  
同步消耗的地方在于并发的时候。你一个线程。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics