0

I found a section in some code at work where a bunch of long strings were created with this format:

String s = "" +
    "...\n" +
    "...\n" +

Just out of curiosity decided to do a quick test to see if a StringBuilder would make any noticeable difference.

public class TestStringConcat {

    public static void main(String[] args) {
        int arraySize = 1000000;
        String[] strings1 = new String[arraySize];
        String[] strings2 = new String[arraySize];

        System.out.println("Testing concat version");

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < arraySize; i++) {
            strings1[i] = "" +
                "A big long multiline string"; //35 lines of string omitted 
        }

        long endTime = System.currentTimeMillis();
        System.out.println("Time to concat strings: " + (endTime - startTime));

        System.out.println("Now testing with stringbuilder ");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < arraySize; i++) {
            StringBuilder sb = new StringBuilder();
            sb.append("A big long multiline string"); //35 lines of string omitted 
            strings2[i] = sb.toString();
        }
        endTime = System.currentTimeMillis();
        System.out.println("Time to build strings with stringbuilder: " + (endTime - startTime));

    }

}

The output:

Testing concat version
Time to concat strings: 5
Now testing with stringbuilder 
Time to build strings with stringbuilder: 2455

I thought StringBuilders where supposed to be faster, but in this case it's way slower. What's going on?

Brent Sandstrom
  • 841
  • 10
  • 16

1 Answers1

7

The first part is not doing any concatenation. The concatenation happens at compile time. All it does is storing the same, unique, long string in all the indices of the array.

A StringBuilder should be used when concatenating in a loop. Even when you're concatenating dynamic stuff at runtime using

"a" + someVar + "b" + someOtherVar;

The compiler generates code that uses a StringBuilder to concatenate (or uses code at least as fast as what a StringBuilder would do, depending on the Java version).

What is slow is:

String s = "";
for (String e : array) {
    s += e;
}

That creates a lot (well, one per element of the array) of temporary strings and a lot of copies of these temporary strings into the next one.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Just thinking - this is wrong these days right: "_The compiler generates code that uses a StringBuilder_" - since JEP280 "Indify String Concatenation" – Boris the Spider Mar 16 '19 at 06:01
  • 1
    @BoristheSpider the generated byte code doesn't use a StringBuilder directly and instead uses indy, but I don't know what is actually used nowadays by the actual implementation of the string concatenation used by the StringConcatFactory invoked by indy. My guess is that it still uses StringBuilder. I'll rephrase anyway. – JB Nizet Mar 16 '19 at 08:30