cobo85 发表于 2013-2-3 13:51:11

Java5.0 对字符串操作的优化

      最近管理层要求把项目中所有的字符串“+”操作修改为StringBuilder/StringBuffer方式进行操作。以前在java5.0发布的时候好像看到过在这个新的编译器版本中对字符串的操作进行了优化,索性就彻底的研究下。
 
     测试代码
     
String s1="********";s1+="--------";s1+="^^^^^^^^";StringBuilder s2=new StringBuilder("********");s2.append("--------");s2.append("^^^^^^^^");    对应的class文件关键字节码
   
astore_1 //s1的是声明   3new java.lang.StringBuilder //JVM把s1优化为StringBuilder   6dup   7aload_1    8invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String     11invokespecial java.lang.StringBuilder(java.lang.String)     14ldc <String "--------">     16invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder //执行“+”操作    19invokevirtual java.lang.StringBuilder.toString() : java.lang.String //操作完成重新转化为String    22astore_1     23new java.lang.StringBuilder //再次把string转化为StringBuilder,重新执行上面的步骤    26dup    27aload_1     28invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String     31invokespecial java.lang.StringBuilder(java.lang.String)     34ldc <String "^^^^^^^^">     36invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder     39invokevirtual java.lang.StringBuilder.toString() : java.lang.String     42astore_1     43new java.lang.StringBuilder //最后转化为StringBuilder ,以备后面可能进行的字符串操作    46dup    47ldc <String "********"> //下面是StringBuilder操作方式的字节码,可以看出没有进行String与StringBuilder的相互转化,直接append。    49invokespecial java.lang.StringBuilder(java.lang.String)     52astore_2     53aload_2     54ldc <String "--------">     56invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder     59pop    60aload_2     61ldc <String "^^^^^^^^">     63invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder  
 这样基本可以得出结论:在5.0以后的版本,对于String直接进行"+"操作,java编译器会把其优化为StringBuilder后再进行append操作,然后进行来回的String<--->StringBuilder的转化,用StringBuilder的话可以会一直的append直道自己进行StringBuilder--->String的转化,因此在效率上String的“+”操作虽然简洁并比1.4以前的版本中的重新生成String对象进行操作有改进,但效率上仍然与StringBuilder有一定的差距,具体差距有多大,下面随便写了个测试代码
 
 
    
String str1="";long start=System.currentTimeMillis();for (int i = 0; i < 20000; i++) {str1+="test";}str1+="--------";long end=System.currentTimeMillis();System.out.println("String耗时"+(end-start));//StringBuilderstart=System.currentTimeMillis();StringBuilder builder=new StringBuilder();for (int i = 0; i < 50000; i++) {builder.append("test");}builder.append("--------");builder.toString();end=System.currentTimeMillis();System.out.println("StringBuilder耗时"+(end-start));//随便测试下StringBufferstart=System.currentTimeMillis();StringBuffer buffer=new StringBuffer();for (int i = 0; i < 50000; i++) {buffer.append("test");}buffer.append("--------");buffer.toString();end=System.currentTimeMillis();System.out.println("StringBuffer耗时"+(end-start)); 
   结果:
String耗时7202
StringBuilder耗时16
StringBuffer耗时0
 
StringBuilder是线程非安全的,StringBuffer是线程安全的,按理来说StringBuilder应该比StringBuffer快才是,但结果有点出乎意料,可能是测试次数少的原因吧,过年了,先写这么多吧。
 
 
页: [1]
查看完整版本: Java5.0 对字符串操作的优化