Java性能陷阱:StringBuffer的性能真的比String好吗?

2014-11-23 23:19:11 · 作者: · 浏览: 0
看了cherami写的 使用String还是StringBuffer 以及后面多为网友的评论,感觉这个问题有必要好好的深究一下,因此编写了一个简单的测试类和一个脚本来运行它。通过修改那个测试类为不同的参数,并且在不同的JDK上测试发现这个问题实在是一个非常有趣的问题。下面让我们开始吧。

第一步,准备工作


为了方便后面测试工作的进行,有必要编写一个简单的脚本:
echo test by jdk1.2.2
/opt/java/jdk1.2.2/bin/javac StringTest.java
/opt/java/jdk1.2.2/bin/java StringTest
echo test by jdk1.3.1_09
/opt/java/jdk1.3.1_09/bin/javac StringTest.java
/opt/java/jdk1.3.1_09/bin/java StringTest
echo test by jdk1.4.2
/opt/java/jdk1.4.2/bin/javac StringTest.java
/opt/java/jdk1.4.2/bin/java StringTest

上面的脚本根据需要可以应用在windows或者linux上,我是在linux进行测试的,因此我把它保存为一个文件stringtest.sh,如果你在windows上测试,你可以保存为stringtest.bat。

意:本文后面的运行结果都是连续运行多次并取其中一个比较平均和典型的样本值)

第二步,开始写代码


最开始我几乎没有怎么考虑就写出了如下的代码:
  1. public class StringTest {
  2. public static void main(String[] args) {
  3. long start=System.currentTimeMillis();
  4. for (int i=0; i<10000; i++) {
  5. String s="This is a "+"long test string for "+"different JDK performance "+"testing.";
  6. }
  7. long end=System.currentTimeMillis();
  8. System.out.println("Directly string contact:"+(end-start));
  9. start=System.currentTimeMillis();
  10. for (int i=0; i<10000; i++) {
  11. StringBuffer buffer = new StringBuffer();
  12. buffer.append("This is a ");
  13. buffer.append("long test string for ");
  14. buffer.append("different JDK performance ");
  15. buffer.append("testing.");
  16. String ss=buffer.toString();
  17. }
  18. end=System.currentTimeMillis();
  19. System.out.println("StringBuffer contact:"+(end-start));
  20. }
  21. }

运行结果:
test by jdk1.2.2
Directly string contact:0
StringBuffer contact:120
test by jdk1.3.1_09
Directly string contact:1
StringBuffer contact:47
test by jdk1.4.2
Directly string contact:0
StringBuffer contact:53

呵呵,是不是大出意外?!!!我开始也是,但是别急,实际上我犯了一个错误,由于进行字符串+操作的都是字符串直接量,因此编译器在编译的时候进行了优化,所以String s="This is a "+"long test string for "+"different JDK performance "+"testing.";编译以后实际上变成了:String s="This is a long test string for different JDK performance testing.";,呵呵,这就是一个简单的赋值操作了,难怪所用的时间几乎没有了。

第三步,修改代码


  1. public class StringTest {
  2. public static void main(String[] args) {
  3. String s1="This is a ";
  4. String s2="long test string for ";
  5. String s3="different JDK performance ";
  6. String s4="testing.";
  7. long start=System.currentTimeMillis();
  8. for (int i=0; i<10000; i++) {
  9. String s=s1+s2+s3+s4;
  10. }
  11. long end=System.currentTimeMillis();
  12. html" target="_blank">