Javac StringBuilder/StringBuffer优化是什么时候引入的?

我知道Javac编译器能够使用/转换字符串串联,我很好奇知道从哪个版本开始引入此更改?+StringBuilderStringBuffer

我正在使用此示例代码:

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_121javac 1.6.0_20javac 1.5.0_22java 1.4.2_19

以下是我看到的字节码示例::javap -c1.4.2_19

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

以下是版本 1 中语言规范的引用

实现可以选择在一个步骤中执行转换和串联,以避免创建然后丢弃中间对象。为了提高重复字符串串联的性能,Java 编译器可以使用类 (§20.13) 或类似技术来减少通过计算表达式创建的中间对象的数量。StringStringBufferString

回到当时,他们有而不是.StringBufferStringBuilder

还引用了JDK1.0.2的StringBuffer的话:

此类是字符的可增长缓冲区。它主要用于创建字符串。编译器使用它来实现“+”运算符。


答案 2

我查阅了Java语言规范,第一版(从1996年开始)。不是一个容易找到,但它在这里。关于串联优化的段落甚至在当时就已经存在了:

实现可以选择在一个步骤中执行转换和串联,以避免创建然后丢弃中间 String 对象。为了提高重复字符串串联的性能,Java 编译器可以使用 StringBuffer 类 (§20.13) 或类似技术来减少通过计算表达式创建的中间 String 对象的数量。

该规范与当时有关,但是(当前JLS措辞所指的)可能被认为性能更好,因为它的方法不同步。StringBufferStringBuilder

然而,这并不意味着人们应该一如既往地依赖优化。例如,循环中的字符串串联将不会得到优化。


推荐