Java += 比 concat 更有效吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4323018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is += more efficient than concat?
提问by Jimmy
I've been reading code produced by other developers on my team, they seem to favor using +=
for String concatenation, whereas I prefer using .concat()
as it feels easier to read.
我一直在阅读我团队中其他开发人员编写的代码,他们似乎更喜欢使用+=
字符串连接,而我更喜欢使用,.concat()
因为它更容易阅读。
I'm trying to prepare an argument as to why using .concat()
is better, and I'm wondering, is there any difference in efficiency between the two?
我试图准备一个关于为什么使用.concat()
更好的论点,我想知道两者之间的效率有什么区别吗?
Which option "should" we be taking?
我们“应该”采取哪个选项?
public class Stuff {
public static void main(String[] args) {
String hello = "hello ";
hello += "world";
System.out.println(hello);
String helloConcat = "hello ".concat("world");
System.out.println(helloConcat);
}
}
采纳答案by Buhake Sindi
Since String is immutable in java, when you do a +
, +=
or concat(String)
, a new String is generated. The bigger the String gets the longer it takes - there is more to copy and more garbage is produced.
因为 String 在 java 中是不可变的,所以当你执行 a +
, +=
or 时concat(String)
,会生成一个新的 String 。字符串越大,需要的时间越长——需要复制的内容越多,产生的垃圾也越多。
Today's java compilers optimizes your string concatenation to make it optimal, e.g.
今天的java编译器优化你的字符串连接以使其最佳,例如
System.out.println("x:"+x+" y:"+y);
Compiler generates it to:
编译器将其生成为:
System.out.println((new StringBuilder()).append("x:").append(x).append(" y:").append(y).toString());
My advice is to write code that's easier to maintain and read.
我的建议是编写更易于维护和阅读的代码。
This link shows performance of StringBuilder vs StringBuffer vs String.concat - done right
此链接显示了StringBuilder 与 StringBuffer 与 String.concat 的性能 - 做得对
回答by darioo
It shouldn't matter. Modern day Java compilers, JVMs and JITs will optimize your code in such a way that differences are likely to be minimal. You should strive to write code that's more readable and maintainable for you.
应该没关系。现代 Java 编译器、JVM 和 JIT 将以一种差异可能最小的方式优化您的代码。您应该努力编写对您来说更具可读性和可维护性的代码。
回答by aioobe
I agree with @darioo and most other answers. Always put readability (and maintainability) first. (A modern JIT compiler should have no troubles with simple cases like these.)
我同意@darioo 和大多数其他答案。始终将可读性(和可维护性)放在首位。(现代 JIT 编译器应该不会遇到像这样的简单情况。)
Here is however the bytecode corresponding to your program. (Note that the +=
approach results in a StringBuilder
which is generally the preferred approach when constructing strings.)
然而,这是与您的程序相对应的字节码。(请注意,该+=
方法导致 a StringBuilder
,这通常是构造字符串时的首选方法。)
// String hello = "hello";
0: ldc #2; //String hello
2: astore_1
// hello += "world";
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method StringBuilder."<init>"
10: aload_1
11: invokevirtual #5; //Method StringBuilder.append
14: ldc #6; //String world
16: invokevirtual #5; //Method StringBuilder.append
19: invokevirtual #7; //Method StringBuilder.toString
// System.out.println(hello);
22: astore_1
23: getstatic #8; //Field System.out
26: aload_1
27: invokevirtual #9; //Method PrintStream.println
// String helloConcat = "hello ".concat("world");
30: ldc #2; //String hello
32: ldc #6; //String world
34: invokevirtual #10; //Method String.concat
37: astore_2
// System.out.println(helloConcat);
38: getstatic #8; //Field System.out
41: aload_2
42: invokevirtual #9; //Method PrintStream.println
45: return
回答by Tom Hawtin - tackline
In terms of readability, I think you are very wrong. +
wins over .concat()
. If you are using +=
, you might want to think about StringBuilder.append
keeping the same StringBuilder
for the loop.
在可读性方面,我认为你是非常错误的。+
赢了.concat()
。如果您正在使用+=
,您可能需要考虑StringBuilder.append
保持StringBuilder
循环相同。
In terms of performance concat
is better than +
. so long as you only use one or perhaps two.
在性能concat
方面优于+
. 只要你只使用一个或两个。
In the case of concat
, you will end up creating a String
object with a correctly sized char[]
. It's about as optimal as you can get.
在 的情况下concat
,您最终将创建一个String
大小正确的对象char[]
。它是您所能获得的最佳状态。
For +
javac generates code that constructs a StringBuilder
to do the appending and then converts to a String
. From 1.5 you create:
对于+
javac 生成的代码构造 aStringBuilder
进行追加,然后转换为String
. 从 1.5 开始,您创建:
- A
StringBuilder
(waste) - Initial
char[]
forStringBuilder
(waste) - If resulting sequence is too long, a second bigger
char[]
(waste) - The resulting
String
. - The
String
'schar[]
.
- A
StringBuilder
(废物) - 初始
char[]
为StringBuilder
(废物) - 如果结果序列太长,第二个更大
char[]
(浪费) - 结果
String
. - 该
String
的char[]
。
However, you rarely see concat
used because it is more difficult to read. The performance is almost certainly going to be a drop in the ocean compared to what else is going on (hint: try the back of an envelope before optimising).
但是,您很少看到concat
使用它,因为它更难阅读。与其他情况相比,性能几乎肯定会是沧海一粟(提示:在优化之前尝试信封的背面)。
回答by Peter Lawrey
You should do what you find is the shortest and clearest to you.
你应该做你认为对你来说最短和最清楚的事情。
However, for your interest.
但是,为了您的利益。
String hello = "hello " + "world";
Is the fastest as the compile combined the two String into one.
是最快的,因为编译将两个 String 合二为一。
This is fastest for two Strings as it avoids creating StringBuilder.
这对于两个字符串来说是最快的,因为它避免了创建 StringBuilder。
String helloConcat = "hello ".concat(world);
However if you have more than two strings Using StringBuilder, either implicitly or explicitly is fastest.
但是,如果使用 StringBuilder 有两个以上的字符串,则隐式或显式最快。
In summary I would use + unless you have it in a loop in which case I might use StringBuilder explicitly to improve performance.
总之,我会使用 + 除非你在循环中使用它,在这种情况下我可能会显式使用 StringBuilder 来提高性能。
回答by Jam Hong
I have found this articaland made this test :
我发现这个ARTICAL并取得该测试:
public static void main(String[] args) {
String s1 = generateString();
String s2 = generateString();
String s3 = generateString();
String s4 = generateString();
String s5 = generateString();
String s6 = generateString();
long e = System.currentTimeMillis();
for(int i=0;i<10000000;i++){
//StringBuilder > concat> plus >StringBuffer >plusEqual(">"means faster than)
//concatPlus(s1 , s2 , s3 , s4 , s5 , s6);//4204ms
//concatBuilder(s1 , s2 , s3 , s4 , s5 , s6);//2562ms
//concatBuffer(s1 , s2 , s3 , s4 , s5 , s6);//4610ms
//concatPlusEqual(s1 , s2 , s3 , s4 , s5 , s6);//9843ms
//concatConcat(s1 , s2 , s3 , s4 , s5 , s6);//3036ms
}
System.out.println(System.currentTimeMillis()-e);
}
public static String concatPlusEqual(String s1, String s2, String s3, String s4,
String s5, String s6) {
String result = "";
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
return result;
}
public static String concatConcat(String s1, String s2, String s3, String s4,
String s5, String s6) {
String result = new String();
result.concat(s1);
result.concat(s2);
result.concat(s3);
result.concat(s4);
result.concat(s5);
result.concat(s6);
return result;
}
public static String concatBuffer(String s1, String s2, String s3, String s4,
String s5, String s6) {
return new StringBuffer(s1.length() + s2.length() + s3.length()
+ s4.length() + s5.length() + s6.length()).append(s1)
.append(s2).append(s3).append(s4).append(s5).append(s6)
.toString();
}
public static String concatBuilder(String s1, String s2, String s3, String s4,
String s5, String s6) {
return new StringBuilder(s1.length() + s2.length() + s3.length()
+ s4.length() + s5.length() + s6.length()).append(s1)
.append(s2).append(s3).append(s4).append(s5).append(s6)
.toString();
}
public static String concatPlus(String s1,String s2,String s3,String s4,String s5,String s6) {
return s1 + s2 + s3 + s4 + s5 + s6;
}
public static String generateString()
{
Random rng = new Random();
int length = 10;
String characters ="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] text = new char[length];
for (int i = 0; i < length; i++)
{
text[i] = characters.charAt(rng.nextInt(characters.length()));
}
return new String(text);
}
It looks like that StringBuilder
is fastest and +=
is slowest.
Just for reference!
看起来这StringBuilder
是最快的,+=
也是最慢的。仅供参考!
回答by Evgeniy Dorofeev
Concat is definitely a faster choice for two strings concatination, I don't know why javac internally uses
concat绝对是两个字符串拼接的更快选择,不知道javac内部为什么用
(new StringBuilder(String.valueOf(s1))).append(s2).toString()
instead of
代替
s1.concat(s2)
for s1 += s2. See my answer to a similar question concatenation operator (+) vs concat()
对于 s1 += s2。请参阅我对连接运算符 (+) 与 concat()的类似问题的回答