예전에도 한 번 해본 것 같은데 잘 기억이 안나서 다시 해봤습니다.

package perfomance;

import org.junit.Before;
import org.junit.Test;
import org.springframework.util.StopWatch;

public class StringAppendTest {

    StopWatch stopWatch;

    @Before
    public void setUp(){
        stopWatch = new StopWatch();
        stopWatch.start();
    }

    @Test
    public void appendByPlus() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByPlusExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Plus: " + stopWatch.getLastTaskTimeMillis());
    }

    @Test
    public void appendByContinuousPlus() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByContinuousPlusExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Continuous Plus: " + stopWatch.getLastTaskTimeMillis());
    }

    @Test
    public void appendByBuilder() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByBuilderExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Builder: " + stopWatch.getLastTaskTimeMillis());
    }

    @Test
    public void appendByBuffer() throws Exception {
        int i = 0;
        while(i < 100000){
            runAppendByBufferExample();
            i++;
        }
        stopWatch.stop();
        System.out.println("by Buffer: " + stopWatch.getLastTaskTimeMillis());
    }

    private void runAppendByContinuousPlusExample() {
        String result = "a";
        result += "bc" + "de";
    }

    private void runAppendByBufferExample() {
        StringBuffer buffer = new StringBuffer("a");
        buffer.append("bc");
        buffer.append("de");

    }

    private void runAppendByBuilderExample() {
        StringBuilder builder = new StringBuilder("a");
        builder.append("bc");
        builder.append("de");
    }

    private void runAppendByPlusExample() {
        String result = "a";
        result += "bc";
        result += "de";
    }

}

결과는 연속 + 연산과 Builder를 사용한 것이 제일 빠릅니다. 연속해서 +를 사용하면 JVM이 내부적으로 StringBuilder를 사용해서 연결해준다고 합니다. 이 테스트 결과를 확인해도 비슷하다는 것을 알 수 있습니다. 결과는 매번 다르지만, 평균적으로 다음과 같이 나옵니다.

위에서 사용한 StopWathch는 스프링 라이브러리에 들어있습니다.
3.0 기준으로 core 번들에 들어있습니다.

by Plus: 46
by Continuous Plus: 16
by Builder: 16
by Buffer: 31