我有一个巨大的字符串如下:
String str = "aaaaaaa"
+ "bbbbbbbb"
+ "cccccccc"
....
+ "zzzzzzzz"; // about 200 lines long
是不是很浪费内存?将它放在一条线上或使用它会更好StringBuilder
吗?这样做是为了创建一个长 sql。
我有一个巨大的字符串如下:
String str = "aaaaaaa"
+ "bbbbbbbb"
+ "cccccccc"
....
+ "zzzzzzzz"; // about 200 lines long
是不是很浪费内存?将它放在一条线上或使用它会更好StringBuilder
吗?这样做是为了创建一个长 sql。
不。如果您的所有字符串都是常量(因为它们在您的问题中) ,编译器将在编译时执行连接。所以最终的表现比版本更好。StringBuilder
否则它将使用StringBuilder
(或StringBuffer
) 来执行任何非常量部分的连接。
所以编译后的版本:
String x = "a" + "b";
应该与以下内容完全相同:
String x = "ab";
请注意,“非常量”部分可能意味着您有时可以明智地使用括号获得(非常小的)额外效率。例如:
int value = ...;
String x = "a" + value + "b" + "c";
...效率低于:
int value = ...;
String x = "a" + value + ("b" + "c");
...作为第一个附加"b"
并且"c"
分开。高效版本等价于O:
int value = ...;
String x = "a" + value + "bc";
我不记得曾经将其用作合法的微优化,但这至少是一个兴趣点。
在当前版本的 Java 中,每个+
(连接)操作都会自动编译为一个操作。但是,如果它在一个循环内,它将为每次迭代创建一个新的,否定它的效果 - 所以你会更好地管理显式。StringBuilder
append()
StringBuilder
StringBuilder
不,编译器会为你优化成StringBuilder
.
编辑:正如 Louis Wasserman 指出的那样,它还会为您组合字符串文字,因此上面的语句在编译时只是一个字符串。
AFAIK JVM 内部有一个字符串池,您创建的每个字符串都存储在那里,丢弃最旧/最少使用的字符串(我不确定它如何选择哪些字符串)。如果你明确地调用 String.intern() 你是在告诉 JVM 将字符串放入池中。
当您使用 + 连接两个字符串时,您最终会在池中得到三个字符串。如果你连接 a + b + c,你最终会得到 5 个字符串 (a, b, ab, c, abc)
至少那是我对旧 JVM 版本的回忆,但 Luiggi 很可能是对的,在较新的版本上它的内部优化
编码:
String str = "aaaaaaa" + "bbbbbbbb" + "cccccccc";
在编译时转换为:
String str = (new StringBuilder()).append("aaaaaaa").append("bbbbbbbb").append("cccccccc").toString();
因此,使用 StringBuilder 似乎没有任何区别。
有一篇非常好的文章将 concat (+) 与 StringBuilder 和 StringBuffer 的性能进行了密切比较,并附有折线图: