String+String和StringBuilder.append(String)的效率和区别
2015-06-30 14:50
405 查看
在写程序的时候以前常用String来直接加,后面慢慢发现这样的效率比较低下,后来改成用StringBuilder或者StringBuffer来进行字符串的拼接。有同事告诉我,其实直接用String+String的方式[下称S+S方式],编译器自己会弄成StringBuilder.append()的方式[下称append方式],我也没有实验过,也不好反对,但是我感觉应该是不对的,所以就有了以下的实验。
实验很简单,就是初始化一个字符串“1”,然后在这个基础上循环一定次数的拼接字符串“1”。
一、首先看看两种方式的运行时间:
1、S+S方式
2、append方式
S+S方式消耗的时间为9099,append方式消耗的时间为17,很明显,S+S方式非常耗费时间,不知道各位看清楚没,S+S只循环了10W次,而append循环了100W次
二、看看两种方式的字节码
1、S+S方式
2、append方式
具体内存变化见图
所以,大量字符串拼接的时候,用StringBuild更理想,更效率,两个字符串拼接的时候倒是无所谓。另外StringBuilder和StringBuffer都比S+S方式更优化,只是StringBuilder是非线程安全的,而StringBuffer是线程安全的
另外附上S+S方式,循环100W次JVM的内存变化图(并未循环完100W次)
实验很简单,就是初始化一个字符串“1”,然后在这个基础上循环一定次数的拼接字符串“1”。
一、首先看看两种方式的运行时间:
1、S+S方式
public class TestString { public static void main(String[] args) { String a="1"; long startTime=System.currentTimeMillis(); for(int i=0;i<100000;i++){ a=a+"1"; } long endTime=System.currentTimeMillis(); System.out.print(endTime-startTime); } }运行时间:
2、append方式
public class TestBuilding { public static void main(String[] args) { StringBuilder a=new StringBuilder("1"); long startTime=System.currentTimeMillis(); for(int i=0;i<1000000;i++){ a.append("1"); } long endTime=System.currentTimeMillis(); System.out.print(endTime-startTime); } }运行时间:
S+S方式消耗的时间为9099,append方式消耗的时间为17,很明显,S+S方式非常耗费时间,不知道各位看清楚没,S+S只循环了10W次,而append循环了100W次
二、看看两种方式的字节码
1、S+S方式
Compiled from "TestString.java" public class TestString extends java.lang.Object{ public TestString(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #2; //String 1 2: astore_1 3: invokestatic #3; //Method java/lang/System.currentTimeMillis:()J 6: lstore_2 7: iconst_0 8: istore 4 10: iload 4 12: ldc #4; //int 100000 14: if_icmpge 43 17: new #5; //class java/lang/StringBuilder 20: dup 21: invokespecial #6; //Method java/lang/StringBuilder."<init>":()V 24: aload_1 25: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 28: ldc #2; //String 1 30: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 33: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 36: astore_1 37: iinc 4, 1 40: goto 10 43: invokestatic #3; //Method java/lang/System.currentTimeMillis:()J 46: lstore 4 48: getstatic #9; //Field java/lang/System.out:Ljava/io/PrintStream; 51: lload 4 53: lload_2 54: lsub 55: invokevirtual #10; //Method java/io/PrintStream.print:(J)V 58: return }
2、append方式
Compiled from "TestBuilding.java" public class TestBuilding extends java.lang.Object{ public TestBuilding(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2; //class java/lang/StringBuilder 3: dup 4: ldc #3; //String 1 6: invokespecial #4; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 9: astore_1 10: invokestatic #5; //Method java/lang/System.currentTimeMillis:()J 13: lstore_2 14: iconst_0 15: istore 4 17: iload 4 19: ldc #6; //int 1000000 21: if_icmpge 37 24: aload_1 25: ldc #3; //String 1 27: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30: pop 31: iinc 4, 1 34: goto 17 37: invokestatic #5; //Method java/lang/System.currentTimeMillis:()J 40: lstore 4 42: getstatic #8; //Field java/lang/System.out:Ljava/io/PrintStream; 45: lload 4 47: lload_2 48: lsub 49: invokevirtual #9; //Method java/io/PrintStream.print:(J)V 52: return }比较两个方式的字节码文件,发现都有StringBuilder的影子,但是不同的是S+S方式每次都有toString这个方法(见S+S字节码33行)并且编译器优化的StringBuilder是每次循环都会new一个,会产生更多的对象所以及其的慢
具体内存变化见图
所以,大量字符串拼接的时候,用StringBuild更理想,更效率,两个字符串拼接的时候倒是无所谓。另外StringBuilder和StringBuffer都比S+S方式更优化,只是StringBuilder是非线程安全的,而StringBuffer是线程安全的
另外附上S+S方式,循环100W次JVM的内存变化图(并未循环完100W次)
相关文章推荐
- Could not reserve enough space for object heap 问题解决
- ios --- 调用系统"设置"里的功能
- android开发过程中自定义动画加载进度条实现过程
- iOS获取设备唯一标识符
- Android*无封装*使用urlconnection和json发送ht
- WebViewJavascriptBridge-Obj-C和JavaScript互通消息的桥梁
- Android textview换行出问题
- 微信支付(0923更新)商户支付密钥key的生成与设置
- HLSL Appendix(HLSL附录)
- Android dp到厘米的转换
- 高级软件测试自学视频(性能、自动化、安全、手机app、管理)
- 在iPhone4的微信,切换效果时背景会闪一下
- SharePoint创建web application出现“The password supplied with the username was not correct”错误的解决方法
- 移动端取消touch高亮效果1
- ios 关闭自动修正输入内容
- Netty游戏服务器之五Unity3d登陆消息
- Netty游戏服务器之五Unity3d登陆消息
- org.tinygroup.application-应用启动框架
- Activity切换动画无效(android:windowIsTranslucent)影响(android:windowAnimationStyle)
- 移动5年 Android生态系统的演进