`
blood
  • 浏览: 2163 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类

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

    博客分类:
  • java
阅读更多

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

 

 

分享到:
评论
19 楼 唯快不破 2010-05-14  
StringBuilder做局部变量放在线程栈内存中本来就是线程安全的啊,为何念念不忘StringBuffer
18 楼 freish 2010-05-14  
这个得看依赖于java语言规范,而不能依赖于某个jre,IBM的jre或者其他的jre都是这种表现么
17 楼 piao_bo_yi 2010-05-14  
8.13 Locks and Synchronization
There is a lock associated with every object. The Java programming language does not provide a way to perform separate lock and unlock operations; instead, they are implicitly performed by high-level constructs that always arrange to pair such operations correctly. (The Java virtual machine, however, provides separate monitorenter and monitorexit instructions that implement the lock and unlock operations.)
16 楼 caiceclb 2010-05-14  
<div class="quote_title">blood 写道</div>
<div class="quote_div">
<p> </p>
<p style="margin: 0px;">这个简单的近乎没有意义的测试(或者因为如此吧,被投了几个“新手贴”, 哈。。。)</p>
<p> </p>
</div>
<p> </p>
<p>就是说,你明知道是新手帖,还不往入门版发喽</p>
15 楼 J-catTeam 2010-05-14  
blood 写道
J-catTeam 写道
同步消耗的地方在于并发的时候。你一个线程。


无语。。。

这里测的不是多线程的锁竞争,而是要看出JIT的运行时编译优化,锁省略优化
诸如循环展开,方法内联等编译优化。






呵呵·是我考虑不周。我研究一下
14 楼 RednaxelaFX 2010-05-14  
请问楼主能否把测试用的完整代码以及完整的命令行启动参数、具体的JDK版本和平台情况标明?如果您只是在一个main()里调用了一次顶楼中的test()方法,那这个计时方式就比较不好了。
13 楼 sdh5724 2010-05-14  
-XX:+UseBiasedLocking
Enables a technique for improving the performance of uncontended synchronization. An object is "biased" toward the thread which first acquires its monitor via a monitorenter bytecode or synchronized method invocation; subsequent monitor-related operations performed by that thread are relatively much faster on multiprocessor machines. Some applications with significant amounts of uncontended synchronization may attain significant speedups with this flag enabled; some applications with certain patterns of locking may see slowdowns, though attempts have been made to minimize the negative impact.


注:  java5.0 下, 这个参数是关闭的。
虽然JIT 优化了非竞争同步, 但是, 程序员们不要依赖这个特定优化。 我相信JIT未必能100%做到这个事情。 特别是一些读共享的代码。 JIT就未必能意识到是不是需要同步。
这个优化对于一些老代码的的确非常有效, 我做过不少测试, 几乎是性能毫无下降。 但是新代码, 不需要使用同步的代码, 尽量不要。
12 楼 esanone 2010-05-13  
StringBuffer,用习惯了.呵呵
11 楼 blood 2010-05-13  
很多人因为习惯,或者老代码,都是用StringBuffer,还多是做局部变量。
当然用StringBuilder是更好的,但因为编译期优化的存在,也可以不用把老代码中的StringBuffer替换回来。
执行几次之后,JIT就会优化成跟StringBuilder接近的性能。




10 楼 blood 2010-05-13  
J-catTeam 写道
同步消耗的地方在于并发的时候。你一个线程。


无语。。。

这里测的不是多线程的锁竞争,而是要看出JIT的运行时编译优化,锁省略优化
诸如循环展开,方法内联等编译优化。





9 楼 J-catTeam 2010-05-13  
同步消耗的地方在于并发的时候。你一个线程。
8 楼 whaosoft 2010-05-13  
谢谢lz吧  又受教了。。 确实一般都用在 方法里 (也就是做局部变量)方法区本来就不是线程安全的 但非要用StringBuffer 这个线程安全的东西 也没吗用。。。 行以后改用StringBuilder
7 楼 leoizumi 2010-05-13  
理论上虽然快...但是,一般都是用StringBuffer ......
6 楼 blood 2010-05-13  
liu78778 写道
明显是猜的, 这也能叫分析


请了解一下JIT再来看是不是猜的吧
5 楼 liu78778 2010-05-13  
明显是猜的, 这也能叫分析
4 楼 csslisi 2010-05-13  
这个结论比较肤浅,像是猜的
3 楼 m7788 2010-05-13  
只能说jvm确实牛。
2 楼 shuiguozheng 2010-05-13  
x_root 写道
局部变量我一般都用StringBuilder.

      jvm 可以自动释放锁的啊?
1 楼 x_root 2010-05-13  
局部变量我一般都用StringBuilder.

相关推荐

    JVM与性能优化知识点整理.rar

    3. JIT编译器:Just-In-Time Compiler,将频繁执行的热点代码编译为机器码,提高执行效率。 4.垃圾收集机制:自动管理内存,防止内存泄漏,包括标记-清除、复制、标记-整理、分代收集等多种算法。 二、JVM性能优化...

    java代码优化总结1.0版本.zip

    14. **预编译表达式(JIT)**:JVM的Just-In-Time编译器可以将频繁执行的热点代码编译为本地机器码,提高执行速度。 以上只是部分可能涵盖的Java代码优化知识点,实际的"java代码优化总结1.0版本.md"文件可能包含更...

    JAVA优化编程.zip

    7. **编译优化**:JIT(Just-In-Time)编译器能够将热点代码编译为机器码,提高运行效率。了解哪些代码会被JIT编译,以及如何使用-XX:+PrintCompilation观察JIT编译情况,有助于优化。 8. **性能监控**:使用工具如...

    java优化代码1.0版本.7z

    7. **编译优化**:JIT(Just-In-Time)编译器将热点代码编译为本地机器码,提高执行效率。通过-XX:+PrintCompilation观察并优化热点代码。 8. **监控与分析**:使用JVisualVM、JProfiler等工具监控CPU、内存、线程等...

    JAVA代码优化[归类].pdf

    - 使用JIT(Just-In-Time)编译器,将热点代码编译为机器码,提升运行速度。 - 使用`-XX:CompileThreshold`等JVM参数调整编译阈值,平衡编译时间和运行速度。 9. **内存管理**: - 了解垃圾回收机制,避免内存...

    Java程序性能优化(23条).doc

    开启JIT(Just-In-Time)编译,让热点代码在运行时转换为机器码,提高执行效率。 13. 泛型和类型擦除: 尽量避免在性能敏感的代码中使用泛型,因为Java的类型擦除会导致额外的类型检查。 14. 精心设计算法: ...

    Java性能优化技巧集锦

    12. **编译优化**:利用JIT(Just-In-Time)编译器将热点代码编译为机器码,提高执行效率。了解并使用逃逸分析和标量替换等编译优化技术。 13. **代码质量**:遵循SOLID原则,编写可维护、可扩展的代码。避免过深的...

    java代码优化1.0版本.zip

    - **使用JIT编译器**:HotSpot JVM的Just-In-Time编译器能将频繁执行的热点代码编译为本地机器码,提升性能。 - **应用启动预热**:在正式发布前,先让程序运行一段时间,让JIT有机会编译热点代码。 8. **日志和...

    Java虚拟机全面了解.zip

    - **执行引擎**:解析并执行字节码,包含解释器和JIT(Just-In-Time)编译器。 - **垃圾收集器**:自动管理内存,回收不再使用的对象,防止内存泄露。 - **本地方法接口**:与操作系统和硬件进行交互,如JNI(Java ...

    Java程序性能优化 让你的Java程序更快、更稳定

    10. **JIT编译器**:理解Just-In-Time编译器的工作方式,优化热点代码,使用-XX:+UseParallelGC或-XX:+UseG1GC等选项提升JIT编译效果。 11. **监控和诊断**:使用JMX、VisualVM、JProfiler等工具进行性能监控和问题...

    java虚拟机规范(java+se+7)中文版

    3. **字节码执行引擎**:解析并执行字节码,包括解释器和JIT(Just-In-Time)编译器。解释器逐行执行字节码,而JIT则将频繁执行的代码编译成机器码以提高效率。 在Java 7中,JVM的主要优化包括: 1. ** ...

    Java程序性能优化之二十三个建议

    16. **使用JIT编译器**: Java的Just-In-Time (JIT)编译器可以将频繁执行的热点代码编译为机器码,提高运行效率。 17. **配置合适的JVM参数**: 根据应用需求调整堆大小、新生代比例、垃圾收集器等JVM参数。 18. **...

    如何优化JAVA程序设计和编码,提高JAVA性能

    9. **编译器优化**:让JIT编译器(Just-In-Time Compiler)发挥作用,通过开启服务器模式(`-server`选项)可以启用更高级的优化。此外,可以使用`-XX:CompileCommand`等JVM参数自定义编译策略。 10. **内存管理**...

    Java基础知识考点Java开卷考试.doc

    Java既不是纯粹的编译型语言(如C++),也不是完全的解释型语言(如早期的Basic),而是采用了编译和解释相结合的方式,被称为“即时编译”(Just-In-Time, JIT)。 Java源文件中,每个公有类(public class)的...

    2021国外Java面试题(纯英文).pdf

    JIT(Just-In-Time)编译器是Java性能优化的关键组件,它在程序运行时将部分字节码转换为机器码,以提高执行效率。 在Java中,equals()方法用于比较对象的内容,而“==”运算符检查两个引用是否指向同一内存位置。...

    Java期末复习1

    然而,Java的自动优化主要发生在JVM的运行时,通过Just-In-Time (JIT) 编译器将热点代码转换为机器码。 3. **字符串操作**: `append`方法是`StringBuilder`或`StringBuffer`类中的,用于在字符串末尾添加新的字符...

    java编程中'为了性能'一些尽量做到的地方

    利用JIT(Just-In-Time)编译器,Java代码可以在运行时被编译为机器码,从而提高执行速度。 15. **监控和分析** 使用JProfiler、VisualVM等工具定期对应用程序进行性能分析,找出瓶颈并针对性优化。 以上是Java...

    十分简单易懂的Java应用程序性能调优技巧分享

    10. **编译优化与代码混淆**:在生产环境中,启用JIT编译(Just-In-Time)可以提高运行时性能。对于移动应用,代码混淆也能提高安全性并减小包体积。 11. **数据库查询优化**:优化SQL查询,减少JOIN操作,使用索引...

Global site tag (gtag.js) - Google Analytics