String StringBuilder StringBuffer 연산 성능 비교하기

dev_hwan·2023년 2월 20일
0

Java에서 문자열을 합치는 방법에는 여러 가지가 있습니다.

이번에는 + 연산자, StringBuilder 클래스의 append 메소드, String.join 메소드, 그리고 StringBuffer 클래스의 append 메소드를 이용하여 문자열을 합치는 성능을 비교해보겠습니다.

이 중에서 가장 빠른 방법은 무엇일지 알아 보겠습니다.

실험 환경

  • Java 버전: OpenJDK 11.0.13
  • 테스트 데이터: 1부터 1,000,000까지의 숫자를 문자열로 변환한 것
  • 실험 횟수: 10번
  • 평균 시간 측정

코드 및 결과

int numOfTests = 10;
int numOfIterations = 1_000_000;

long[] elapsedTime = new long[4];
for (int i = 0; i < numOfTests; i++) {
	elapsedTime[0] += measureConcatenation(numOfIterations);
    elapsedTime[1] += measureStringBuilder(numOfIterations);
    elapsedTime[2] += measureStringJoin(numOfIterations);
    elapsedTime[3] += measureStringBuffer(numOfIterations);
}

System.out.println("Average Time:");
System.out.println("+ 연산자: " + elapsedTime[0] / numOfTests + "ms");
System.out.println("StringBuilder: " + elapsedTime[1] / numOfTests + "ms");
System.out.println("String.join: " + elapsedTime[2] / numOfTests + "ms");
System.out.println("StringBuffer: " + elapsedTime[3] / numOfTests + "ms");

+ 연산자

private static long measureConcatenation(int numOfIterations) {
    long start = System.currentTimeMillis();
    String result = "";
    for (int i = 0; i < numOfIterations; i++) {
        result += Integer.toString(i);
    }
    long end = System.currentTimeMillis();
    return end - start;
}

StringBuilder 클래스의 append 메소드

private static long measureStringBuilder(int numOfIterations) {
    long start = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < numOfIterations; i++) {
        sb.append(Integer.toString(i));
    }
    String result = sb.toString();
    long end = System.currentTimeMillis();
    return end - start;
}

String.join 메소드

private static long measureStringJoin(int numOfIterations) {
    long start = System.currentTimeMillis();
    List<String> list = new ArrayList<>();
    for (int i = 0; i < numOfIterations; i++) {
        list.add(Integer.toString(i));
    }
    String result = String.join("", list);
    long end = System.currentTimeMillis();
    return end - start;
}

StringBuffer 클래스의 append 메소드

private static long measureStringBuffer(int numOfIterations) {
    long start = System.currentTimeMillis();
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < numOfIterations; i++) {
        sb.append(Integer.toString(i));
    }
    String result = sb.toString();
    long end = System.currentTimeMillis();
    return end - start;
}

실행결과

Average Time:
+ 연산자: 1260ms
StringBuilder: 4ms
String.join: 15ms
StringBuffer: 21ms

결과분석

위의 결과를 보면, + 연산자를 이용한 방법이 가장 느리고, StringBuilder 클래스의 append 메소드를 이용한 방법이 가장 빠릅니다. 그리고 String.join 메소드와 StringBuffer 클래스의 append 메소드는 비슷한 성능을 보입니다.

1. + 연산자

  • 문자열을 합치는 코드가 간단한 경우에 사용합니다.
  • 예를 들어, 두 개의 문자열을 합치는 경우나 문자열을 상수와 함께 출력하는 경우에 적합합니다.

2.StringBuilder 클래스의 append 메소드

  • 문자열을 합칠 때 마다, 새로운 문자열을 생성하여 문자열이 길어질수록 성능이 떨어지는 것으로 보입니다.

3. String.join 메소드

  • 구분자(separator)를 이용하여 문자열을 합치는 경우에 사용합니다.
  • String.join은 내부적으로 StringBuilder를 이용하여 문자열을 합치기 때문에, 성능상 이점이 있습니다. 또한 가변인자(varargs)를 이용하여 여러 개의 문자열을 합치는 것도 가능합니다.

4. StringBuffer 클래스의 append 메소드

  • 멀티스레드 환경에서 안전하게 문자열을 합치는 경우에 사용합니다.
  • StringBuffer는 내부적으로 synchronized를 이용하여 동기화 처리를 하기 때문에, 멀티스레드 환경에서 안전하게 사용할 수 있습니다. 그러나 StringBuilder보다는 성능이 떨어지기 때문에, 단일 스레드 환경에서는 StringBuilder를 사용하는 것이 좋습니다.
profile
내맘대로 주제잡고 재미로 글쓰는 개발일지 블로그 👨‍💻

0개의 댓글