Am 31.12.2014 um 19:15 schrieb chaitanya bhatt:
Concatenation with + operator will be internally converted to a
StringBuffer( as synchronized version of StringBuilder class). IMO there
isn't much performance difference unless you are trying to concatenate in a
loop, in such cases StringBuilder would be a better option.
No, the example I stated was not a loop, but quite static. At least java
6 seems to compile such static "+" operators to StringBuilder. That is
what javap -c shows on my test classes. The jls for java5 cited below
states, that it may be converted to a StringBuffer, but that that is
left to the compiler. Seems the compiler people moved on.
Also, since StringBuffer is synchronized, depending on how you are using
the String object in the VM StringBuilder may outperform "+" approach.
(Take a look a the StackOverflow discussion)
I have done a simple microbenchmark, which shows the simple + operator
to be the fasted of the three variants "+", StringBuilder and
StringBuffer, with StringBuilder being just a bit slower. Which is
probably more luck than anything else, since the bytecode decompiles to
the same instructions. StringBuffer is slowest (as expected, but not
that much) (Code compiled with java 6 and run with Java 6, 7 and 8)
Also, I feel StringBuilder improves readability of a code.
I feel a simple "+" is more readable than a constructor plus two or more
calls of append. But that is why I asked :)
Regards
Felix
Plus,
http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.18.1.2
http://stackoverflow.com/questions/355089/stringbuilder-and-stringbuffer
Chaitanya M Bhatt
http://www.performancecompetence.com
On Sun, Dec 28, 2014 at 4:34 AM, Felix Schumacher <
[email protected]> wrote:
Hi all,
in XPathUtil I have found the following code fragment:
log.debug(new StringBuilder("bla").append(blub).append("whatever").
toString())
which seems to me t be equivallent to
log.debug("bla"+blubb+"whatever")
any reason to use the former?
Regards
Felix
import akka.util.Collections;
import scala.actors.threadpool.Arrays;
public class StringConcatenationTests {
private interface StringConcatTester {
String concat(long i);
}
private static class ConcatWithPlus implements StringConcatTester {
@Override
public String concat(long value) {
return "value: " + value + "!";
}
}
private static class ConcatWithStringBuilder implements StringConcatTester {
@Override
public String concat(long value) {
return new StringBuilder("value: ").append(value).append("!")
.toString();
}
}
private static class ConcatWithStringBuffer implements StringConcatTester {
@Override
public String concat(long value) {
return new StringBuffer("value: ").append(value).append("!")
.toString();
}
}
private static void test(StringConcatTester tester, long range) {
long startTime = System.currentTimeMillis();
int hash = 0;
for (long i = 0; i < range; i++) {
hash += tester.concat(i).hashCode();
}
long endTime = System.currentTimeMillis();
System.out.println(tester.getClass().getSimpleName() + "; "
+ range + "; "
+ (endTime - startTime) + " ms; "
+ ((endTime - startTime * 1.0) / range) + " ms/call; " + hash);
}
public static void main(String[] args) {
StringConcatTester concatWithPlus = new ConcatWithPlus();
StringConcatTester concatWithStringBuilder = new ConcatWithStringBuilder();
StringConcatTester concatWithStringBuffer = new ConcatWithStringBuffer();
for (StringConcatTester tester : new StringConcatTester[] {
concatWithPlus, concatWithStringBuffer, concatWithStringBuilder }) {
test(tester, 10000);
}
for (StringConcatTester tester : new StringConcatTester[] {
concatWithPlus, concatWithStringBuffer, concatWithStringBuilder }) {
test(tester, 100000000);
}
}
}