字符串连接中的“+”是否会影响效率?

我在java中使用过String,StringBuilder和StringBuffer。
我想到了这个问题,而我从效率的角度思考。

字符串连接中的“+”是否会影响效率?

是的,但是在大多数情况下它都不重要。

对字符串常量使用’+’是最有效的,因为编译器可以执行连接。

如果要连接两个字符串,则concat方法是最有效的,因为它避免使用StringBuilder。

除了向后兼容性之外,几乎没有充分的理由使用StringBuffer。 StringBuilder或StringWriter是更好的选择。 但是,它仍然比JDK中的StringBuilder更频繁地使用:P

StringBuffer是死的,长寿命的StringBuffer

如果你在一个语句中连接,那么它将无关紧要,因为编译器/ JIT编译器将使用StringBuilder自动优化它。

所以"a"+b+"c"将被优化为(new StringBuilder("a").append(b).append("c")).toString()

但是,如果你在一个循环中连接大量的String ,肯定会明确地使用StringBuilder因为它会显着加快你的程序。

 String a = ""; for( int i = 0; i < 1000000; i++ ) a += i; 

应该改为

 StringBuilder sb = new StringBuilder(); for( int i = 0; i < 1000000; i++ ) sb.append(i); String a = sb.toString(); 

有点是,但仍然没有

来自JLS,15.18.1.2

字符串连接的优化

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

对于基本类型,实现还可以通过直接从基元类型转换为字符串来优化包装器对象的创建。

在你的例子中:

 " Does +" + " use in String concatenation affect efficiency? " 

我们必须使用文字字符串,它可能会被编译器取代,所以这比StringBuffer / append / toString更快。

但效率/速度比什么呢? 代码执行? 代码写作? 代码阅读?

自从读了一个

 "Foo = " + foo; 

很容易,我会推荐它,只要不重复一百万次,或者是“s + = s2”; 重复一次hundret时代。

特别,

 System.out.println ("Player " + n + " scores " + player[n].score); 

可读性远远高于

 System.out.println (new StringBuffer ("Player ").append ((Integer.valueOf (n)).toString ().append (" scores ").append (... 

只需在需要高性能的应用程序中避免它,或者连接大量的字符串,或者递归地连接大量的字符串。

由于字符串是不可变的,因此连接字符串会导致字符串创建。 即“A”+“B”+“C”导致“AB”的创建,然后是“ABC”。 如果你正在进行多个连接,那么使用StringBuilder总是更有效率(不是更老但是api相同的StringBuffer,它具有同步成本)

如果你有一个单行连接,编译器会尽可能为你做这个 – 也就是说,如果你编译“A”+“B”+“C”你可能会看到,如果你反编译,像新的StringBuilder( “A”)。附加( “B”)。附加( “C”)。的toString()。 但是编译器无法在多行上优化多个字符串连接 – 也就是说,如果你有多个连接行,你会在每一行看到类似上面的内容,包括额外的StringBuilder创建。 最好手动完成。

您可以通过组合一个简单的示例和反编译来自行validation。

如果你使用’+’多次连接,那么在某种程度上是肯定的。 当你执行String a + String b时,它实际上是在内部创建一个StringBuffer对象并使用StringBuffer的append()。 因此,每次执行’+’时,都会创建一个新的临时StringBuffer对象,使用“a”初始化,然后附加“b”,然后将其转换为字符串对象。

所以如果你需要多个连接,你应该创建一个StringBuffer(线程安全)/ StringBuilder(而不是线程安全)对象并继续追加,这样就可以避免一次又一次地创建StringBuffer对象。