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

时间:2011-08-03 13:49:51

标签: java string performance stringbuffer

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

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

6 个答案:

答案 0 :(得分:5)

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

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

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

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

StringBuffer is dead, long live StringBuffer

答案 1 :(得分:4)

如果你在单个语句中连接,那么无关紧要,因为编译器/ 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();

答案 2 :(得分:1)

有点是,但仍然

来自JLS,15.18.1.2

字符串连接的优化

  

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

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

答案 3 :(得分:1)

在你的例子中:

" 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 (...

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

答案 4 :(得分:-1)

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

如果您有单行连接,编译器会尽可能为您执行此操作 - 也就是说,如果您编译“A”+“B”+“C”,您可能会看到,如果您反编译,类似于new StringBuilder(“A”)。append(“B”)。append(“C”)。toString()。但是,编译器无法在多行上优化多个字符串连接 - 即,如果您有多个连接行,您将在每行上看到类似上面的内容,包括额外的StringBuilder创建。最好手动完成。

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

答案 5 :(得分:-1)

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

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