Whiteship's Note

문자열 연결 성능 비교

모하니?/Coding : 2009.04.27 18:06


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

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

top

  1. Kevin 2009.04.27 19:53 PERM. MOD/DEL REPLY

    저도 비슷한 테스트를 한적이 있습니다만, 따로 JUnit 같은건 안 쓰고,
    그냥 테스트 프로그램을 작성했는데, 아... 이거 결과를 위키에 올린다 올린다 하면서
    계속 미루고 있네요...^^;

    String은 immutable 이기 때문에 그렇죠. 그래서 매번 + operator를 써서
    더해줄때마다 원래 String에 더해지는게 아니라,
    원래 String + 추가된 내용을 저장할 메모리를 새로 할당해서
    reference를 그쪽으로 옮기는거기 때문에...
    +로 계속 assign을 시키면, 시킬때마다 String object이 계속 생성되는거죠.
    아시다 시피, 메모리 생성에 비용이 많이 들기 때문에 느려질수 밖에 없겠죠.

    이미 말씀하셨지만, + 를 연속 사용하고 한번에 assign하면
    Compiler가 알아서 StringBuilder로 대체를 하기 때문에 성능이 제일 좋죠.
    (근데 JVM이 아니라 Compiler가 코드를 대체해서 생성하는걸로 알고 있습니다만...?).

    StringBuffer 랑 StringBuilder 는 거의 비슷한데, StringBuffer는
    thread-safe고 StringBuilder는 아니라서 StringBuilder가 속도가 더 빠릅니다.
    Vector랑 ArrayList 혹은 Hashtable과 HashMap 의 경우랑 비슷하죠. :)
    JDK 소스 살펴 보시면, StringBuffer에 있는 method들은
    synchronized 된걸 볼수있죠.

    String concatenation 하는 코드를 더 빠르게 돌게 만들려면,
    StringBuilder 생성할때 최종적으로 저장될 글자 갯수 전체의
    크기까지 정해 버리면 더 빨라집니다.
    StringBuilder stringBuilder = new StringBuilder(20);

    근데, 코드가 지저분해지고, 앞으로 새로 나올 Java Platform 에서
    자동으로 속도 향상을 시도하는것에 방해가 될 가능성도 있으므로 비추 합니다. :)

    근데 희한한게, 제가 테스트 할때는 연속 +로 한번에 assign 한거보다
    StringBuilder가 항상 좀더 빠른 결과를 보여주더라구요.
    이론대로면 둘이 같거나 연속 +가 조금 더 빨라야 하는데...ㅡ_ㅡ;;;

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2009.04.27 20:56 PERM MOD/DEL

    헉.. 이렇게 자세한 설명을 달아주시다니.
    감사합니다. 위 테스트에 대한 해설판이네요.

  2. 도리 2009.05.11 10:34 PERM. MOD/DEL REPLY

    버전을 명기해 주시면 더 좋을거같아요..
    JDK 버전별로 조금씩 다를텐데.. ^^

    Favicon of http://whiteship.me BlogIcon 기선 2009.05.11 12:56 PERM MOD/DEL

    넵. 1.6에서 했었습니다.

Write a comment.




: 1 : ··· : 142 : 143 : 144 : 145 : 146 : 147 : 148 : 149 : 150 : ··· : 299 :