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]