StringBuiler与String
为什么说StringBuilder append方法比String拼接性能好
比较下面代码
public class StringDemo {
public void byString(){
String str="";
for (int i=0;i<10;i++){
str+=i;
}
}
public void byStringBuilder(){
StringBuilder stringBuilder=new StringBuilder();
for (int i=0;i<10;i++){
stringBuilder.append(i);
}
}
}
通过javac编译代码,再通过javap -c 反编译字节码。
先看String拼接
public com.ognice.demo.StringDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void byString();
Code:
0: ldc #2 // String 加载字符串变量
2: astore_1
3: iconst_0
4: istore_2
5: iload_2
6: bipush 10
8: if_icmpge 36
11: new #3 // class java/lang/StringBuilder 新建SpringBuilder对象
14: dup
15: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 初始化StringBuilder 为str
18: aload_1
19: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 字符串拼接
22: iload_2
23: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
26: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 返回StringBuilder字符串
29: astore_1
30: iinc 2, 1
33: goto 5 // 跳到指令5,循环
36: return
}
解析下指令,指令11-30为循环体内指令,可以看到每次循环都新建一个StringBulider初始化值为str,然后str+=i,使用刚刚新建的StringBuilder执行append拼接字符,最后返回StringBuilder.toString。
再来对比下使用StringBuilder字节码
public void byStringBuilder();
Code:
0: new #3 // class java/lang/StringBuilder
3: dup
4: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
7: astore_1
8: iconst_0
9: istore_2
10: iload_2
11: bipush 10
13: if_icmpge 28
16: aload_1
17: iload_2
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
21: pop
22: iinc 2, 1
25: goto 10
28: return
指令16-22 为循环体内指令,可以看到并没有创建新的对象,直接使用初始化的StringBuilder进行拼接,省去了对象的创建,提高了性能。
这就是为什么说字符串拼接使用StringBuilder性能更高的原因。
网友评论