java何时引入Javac StringBuilder/StringBuffer优化?
我知道Javac编译器能够使用StringBuilder
/StringBuffer
转换字符串连接+
,我很想知道这个更改是从哪个版本开始的
我正在使用以下示例代码:
public class Main {
public static void main(String[] args) {
String a = args[0];
String s = "a";
s = s + a;
s = s + "b";
s = s + "c";
s = s + "d";
s = s + "e";
System.out.println(s);
}
}
到目前为止,我已经尝试了javac 1.8.0_121
、javac 1.6.0_20
、javac 1.5.0_22
和java 1.4.2_19
下面是我使用1.4.2_19
中的javap -c
看到的字节码示例:
6: astore_2
7: new #3; //class StringBuffer
10: dup
11: invokespecial #4; //Method java/lang/StringBuffer."<init>":()V
14: aload_2
15: invokevirtual #5; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
18: aload_1
19: invokevirtual #5; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
22: invokevirtual #6; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
所有4个版本似乎都在使用StringBuilder/StringBuffer优化,所以我很想知道从哪个Javac版本开始引入这个更改
# 1 楼答案
以下是来自language specification from version 1的一段话:
当时,他们用
StringBuffer
代替了StringBuilder
也引用了JDK1的^{} 。0.2:
# 2 楼答案
这并没有回答问题,但我只想补充一点,在jdk-9中,这个
StringBuilder::append
是允许的策略之一,但不是默认策略它实际上是用于字符串连接的
invokedynamic
字节码,因此它的实现现在是特定于JRE的,而不是编译器的。默认策略btw是:MH_INLINE_SIZED_EXACT
# 3 楼答案
我查阅了Java语言规范第一版(1996年起)。不容易找到,但是here it is。即使在那时,也有关于串联优化的文章:
该规范与
StringBuffer
相关,但是StringBuilder
(当前JLS措辞所指)可能被认为性能更好,因为它的方法不同步然而,这并不意味着人们应该依赖于优化,因为总是。例如,循环中的字符串连接不会得到优化
# 4 楼答案
一些答案中已经给出了JLS。我只想强调一点,StringBuffer(https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html)从1.0开始就存在了
StringBuilder(https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)的版本是1.5。请参见相应javadocs的
since:
部分