Java String Concatenation

1:38 PM EDT Thursday, March 15 2007

I was having a discussion with a co-worker today regarding String concatenation in Java. Somewhere along the line, I was told that the Java + operator, when applied to String, was slow when compared to using the append method of StringBuffer or StringBuilder. Tuns out this is a myth, sort of. I wrote a class to test it. This will first concatenate a String 100 times using the + operator, and then build the same string using StringBuilder's append method:

public class StringTest {

    private int iterations;

    public static void main(String[] args) {
        StringTest test = new StringTest(100);
        for(int i = 0; i < 10; i++) {
            test.concat();
            test.append();
        }
    }

    public StringTest(int iterations) {
        this.iterations = iterations;
    }

    private void concat() {
        String foo = "";
        long start = System.currentTimeMillis();
        for(int i = 0; i < iterations; i++) {
            foo += "foo";
        }
        System.out.println("String concat took "+(System.currentTimeMillis()-start)+" ms");
    }

    private void append() {
        StringBuilder sb = new StringBuilder();
        long start = System.currentTimeMillis();
        for(int i = 0; i < iterations; i++) {
            sb.append("foo");
        }
        System.out.println("String append took "+(System.currentTimeMillis()-start)+" ms");
    }

}

The results of this test are:

String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms

So, when concatenating 100 strings, using the + incurs no significant overhead. But, if we run the same test concatenating 10000 String instead, these are the results:

String concat took 1812 ms
String append took 0 ms
String concat took 1766 ms
String append took 0 ms
String concat took 1766 ms
String append took 0 ms
String concat took 1812 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms
String concat took 1828 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms
String concat took 1782 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms

So the Java String concatenation myth is rooted in fact, but as stated on this article on Java Practices, you should use the + operator whenever you are manually concatenating a bunch of Strings, like String foo = "foo"+x+"bar"+y+"baz"+z;, because for that few of a number of Strings, the code is cleaner using the + operator and the overhead of the operator is insignificant. But, if you are pulling data from an external source and building a large String by concatenating many smaller Strings, the StringBuilder would be better to use.

Posted in  | Tags Java

Comments Feed

1. If you decompile the .class file you'll see that you are using StringBuilder on both append() and concat() methods:

private void concat()
{
String s = "";
long l = System.currentTimeMillis();
for(int i = 0; i < iterations; i++)
s = (new StringBuilder()).append(s).append("foo").toString();

System.out.println((new StringBuilder()).append("String concat took ").
append(System.currentTimeMillis() - l).append(" ms").toString());
}

private void append()
{
StringBuilder stringbuilder = new StringBuilder();
long l = System.currentTimeMillis();
for(int i = 0; i < iterations; i++)
stringbuilder.append("foo");

System.out.println((new StringBuilder()).append("String append took ").
append(System.currentTimeMillis() - l).append(" ms").toString());
}

# Posted By Jani on Thursday, October 25 2007 at 09:00 EDT

2. According to the Java Language Specification on String concatenation:
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18.1.2, it's possible the compiler will throw out toString() calls if it can.

It's not in this case because '+=' has no choice but to force toString() to be called on each iteration. In a more likely use case, '+' would be used for string concatenation, and it would be a lot more efficient. I think you would find that StringBuilder and '+' are actually about the same since the toString() calls get thrown out by the compiler.

# Posted By Leo Przybylski on Tuesday, May 06 2008 at 12:47 EDT

3. Hi,

While I was working on a Base64 encode/decoding class I basically came across a speed problem. I finally found out that the += operator on a String object is very slow.

I found myself a really fast work around though. Instead of adding one character at a time, I made sure I had a empty char[] the size the String had to be too. Instead of adding a character to the string each time I needed to I added the character to the char[].

Finally all you have to do is create a new String object using the filled char[]. So new String(arrayOfCharacters[]) for example. I know this is a response too an old post, but came across it on the internet and just really felt the urge to share my solution with you.

The same operation with += operator on a String now takes me several ms, most of the times somewhere between 0 and 300 ms depending on the size of the operation while the += operator ranged from somewhere between the 0 ms and several minutes!

Hope my response was usefull in a way. If any questions, or examples are wanted I'd be happy to share them with you as well.

Greetings,

# Posted By Arjen on Monday, July 07 2008 at 10:20 EDT

Add a Comment