Ant*_*nev 22 java performance java-8 java-9
我有以下代码:
StringBuilder str = new StringBuilder("foo");
for(Field f : fields){
str.append("|" + f);
}
str.append("|" + bar);
String result = str.toString();
Run Code Online (Sandbox Code Playgroud)
我知道编译器会优化字符串连接"|" + f并用StringBuilder替换它.但是,是否会创建一个新的StringBuilder,或者现有的str将在Java 8中使用?Java 9怎么样?
Eug*_*ene 23
默认情况下,java-9中没有StringBuilder字符串连接 - 它是运行时决定它是如何通过invokedynamic.而默认的策略是不是一个StringBuilder::append一个.
您还可以在这里阅读更多内容.
在java-8下,将创建一个新的(很容易invokespecial // Method java/lang/StringBuilder."<init>":()V在解编译的字节码中发现两次出现).
另外,你有一个建议append.append...; 只是注意到这要好得多sb.append ... sb.append,这就是为什么.
由于字符串连接优化由Java编译器执行,您可以通过反编译字节代码来查看它的作用:
$ cat Test.java
interface Field {}
public class Test {
static String toString(Field[] fields, Object bar) {
StringBuilder str = new StringBuilder("foo");
for(Field f : fields){
str.append("|" + f);
}
str.append("|" + bar);
return str.toString();
}
}
$ javac Test.java
$ javap -c Test.class
Compiled from "Test.java"
public class stackoverflow.Test {
public stackoverflow.Test();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
static java.lang.String toString(stackoverflow.Field[], java.lang.Object);
Code:
0: new #16 // class java/lang/StringBuilder
3: dup
4: ldc #18 // String foo
6: invokespecial #20 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
9: astore_2
10: aload_0
11: dup
12: astore 6
14: arraylength
15: istore 5
17: iconst_0
18: istore 4
20: goto 53
23: aload 6
25: iload 4
27: aaload
28: astore_3
29: aload_2
30: new #16 // class java/lang/StringBuilder
33: dup
34: ldc #23 // String |
36: invokespecial #20 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
39: aload_3
40: invokevirtual #25 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
43: invokevirtual #29 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
46: invokevirtual #32 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
49: pop
50: iinc 4, 1
53: iload 4
55: iload 5
57: if_icmplt 23
60: aload_2
61: new #16 // class java/lang/StringBuilder
64: dup
65: ldc #23 // String |
67: invokespecial #20 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
70: aload_1
71: invokevirtual #25 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
74: invokevirtual #29 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
77: invokevirtual #32 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
80: pop
81: aload_2
82: invokevirtual #29 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
85: areturn
}
Run Code Online (Sandbox Code Playgroud)
如您所见,代码Method java/lang/StringBuilder."<init>":在3个位置调用StringBuilder构造函数(),因此将在每次迭代中创建新的StringBuilders(除非实时编译器执行花式优化).
这不太可能是一个重大的性能问题,但在不太可能的情况下,你可以通过重写来轻松解决这个问题
str.append("|").append(f);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2482 次 |
| 最近记录: |