Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Archives
Today
Total
관리 메뉴

csct3434

[자바 성능 튜닝 이야기] 03. String vs StringBuffer vs StringBuilder 본문

개발 서적/자바 성능 튜닝 이야기

[자바 성능 튜닝 이야기] 03. String vs StringBuffer vs StringBuilder

csct3434 2024. 4. 28. 21:49

StringBuilder 클래스와 StringBuffer 클래스

  • StringBuilder와 StringBuffer가 제공하는 메서드는 동일
  • StringBuffer는 ThreadSafe하게 설계되어 있으므로 여러 스레드에서 객체를 공유할 때 사용
  • StringBuilder는 단일 스레드에서의 안정성만 보장하므로 여러 스레드에서 공유할 경우 동시성 문제가 발생

String vs StringBuffer vs StringBuilder 

package org.example;

public class Main {

    private static final String value = "abcde";

    private void testString() {
        String a = new String();
        for (int loop = 0; loop < 1000000; loop++) {
            a += value;
        }
    }

    private void testStringBuffer() {
        StringBuffer stringBuffer = new StringBuffer();
        for (int loop = 0; loop < 1000000; loop++) {
            stringBuffer.append(value);
        }
        String b = stringBuffer.toString();
    }

    private void testStringBuilder() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int loop = 0; loop < 1000000; loop++) {
            stringBuilder.append(value);
        }
        String c = stringBuilder.toString();
    }
}

응답 시간

주요 소스 부분 응답 시간 (ms) 비고
a += value; 95,801.41 95초
stringBuffer.append(value);
String b = stringBuffer.toString();
247.78
14.21
0.24초
stringBuilder.append(value);
String c = stringBuilder.toString();
174.17
13.38
0.17초

 

메모리 사용량

주요 소스 부분 메모리 사용량(bytes) 생성된 임시 객체 수 비고
a += value; 100,102,000,000 4,000,000 약 95Gb
stringBuffer.append(value);
String b = stringBuffer.toString();
29,493,600
10,004,000
1,200
200
약 28Mb
약 9.5Mb
stringBuilder.append(value);
String c = stringBuilder.toString();
29,493,600
10,004,000
1,200
200
약 28Mb
약 9.5Mb

 

원인 분석

  • String은 불변 객체이므로 'a += value;'를 수행하면 두 문자열이 합쳐진 새로운 String 객체가 생성되어 변수 a에 할당되고, 이전의 객체는 쓰레기 값이 되어 GC의 대상이 된다. 이러한 작업이 반복되면서 결국 GC가 수행되고, 이에 따라 응답 속도에 많은 영향을 미치는 것이다.
  • StringBuffer와 StringBuilder는 String과 다르게 새로운 객체를 생성하지 않고, 기존에 있는 객체의 크기를 증가시키면서 문자열을 합친다.

버전에 따른 차이

  • JDK 5.0 이상의 버전부터는 String 객체에 대한 '+' 연산을 컴파일러가 자동으로 StringBuilder로 변환한다.

사용 시기 정리

String

  • 짧은 문자열을 더할 경우 사용

StringBuffer

  • 스레드에 안전한 프로그램을 작성할 경우
  • 개발 중인 시스템이 스레드에 안전한 지 모를 경우
  • static으로 선언한 문자열을 변경하는 경우, 싱글톤으로 선언된 클래스에 선언된 문자열을 변경하는 경우

StringBuilder

  • 스레드 안전성을 고려할 필요가 없는 경우