Одна конкатенация строк создает новый объект String:
"a" + "b" + "c" + "d" // 4 Strings
"ab" // 1 String
"abc" // 1 String
"abcd" // 1 String
// 7 String instances in total (& in theory / worst case)
StringBuilder создает меньше объектов:
StringBuilder sb = new StringBuilder("a").append("b").append("c").append("d")
// 4 Strings, 1 StringBuilder
= 5 objects (in theory/worst case)
Но компилятор знает об этой проблеме, и если вы посмотрите на байт-код файлов классов, достаточно часто вы увидите, что конкатенации строк были заменены на StringBuilder и добавлены. Имея это в виду, вы можете сосредоточиться на читабельном коде и предоставить его компилятору для поиска наиболее производительного решения.
Лично я использую выделенный StringBuilder только в том случае, если мне нужно собрать большие строки (например, исходный код Java или HTML-страницы) или если я использую циклы для сборки строк, например:
String result = "";
for (int i = 0; i < 100; i++)
result += "."; // Ouch - this should be done with StringBuilder