비교할 문제

String 결합 성능에서 확인할 질문은 반복문 안 String +StringBuilder.append의 할당 차이는 언제 커지는가입니다. 완전히 같은 문자열과 encoding 전 단계 결과를 반환하게 하고 작은 고정식과 반복 누적을 분리합니다. 결과값, 순서, 오류 처리와 부수 효과가 다르면 같은 성능 비교가 아닙니다. 먼저 두 후보가 같은 일을 하는지 작은 입력으로 확인합니다.

원인 분석과 재현

반복문에서 immutable String을 계속 +로 누적하면 중간 복사가 늘 수 있지만 한 표현식의 결합은 compiler가 최적화할 수 있습니다.

결합 10회·1,000회, 짧은 문자열·Unicode에서 JDK version, allocation rate와 GC를 JMH로 측정합니다. runtime version, 운영체제, CPU와 memory 제한도 결과와 함께 기록합니다.

비교 질문은 반복문 안 String +StringBuilder.append의 할당 차이는 언제 커지는가입니다.

후보 유리한 조건 함께 치르는 비용
+ 고정식 짧고 고정된 표현 compiler가 최적화할 수 있어 반복 누적과 결과가 다름
+ 반복 누적 아주 작은 횟수 중간 String 복사와 allocation이 반복될 수 있음
StringBuilder 반복·조건부 조립 capacity와 공유 범위를 잘못 잡으면 memory·동시성 비용
@State(Scope.Thread)
public class StringBenchmark {
  @Param({"10", "1000"}) int size;
  @Benchmark public String plusInLoop() {
    String result = ""; for (int i = 0; i < size; i++) result += i; return result;
  }
  @Benchmark public String builder() {
    StringBuilder result = new StringBuilder(); for (int i = 0; i < size; i++) result.append(i); return result.toString();
  }
}
// 예: -wi 5 -i 10 -f 3. 작은 고정식의 +와 반복문 안 누적은 별도 사례입니다.

해결 방안과 판정

warm-up과 측정 구간을 나누고 여러 번 반복합니다. 서비스 지연은 median과 p95를, 처리량 비교는 단위 시간당 완료 수와 오류율을 함께 기록합니다. CPU time, allocation, RSS·heap, GC, I/O 중 이 작업에 직접 관련된 지표만 선택합니다. 가독성이 좋은 짧은 +까지 일괄 교체하지 않습니다. 반복 횟수와 allocation profile에서 차이가 확인되는 경로에 StringBuilder를 사용합니다.

차이가 반복 실행의 흔들림보다 작다면 더 단순하고 읽기 쉬운 구현을 선택합니다. 차이가 충분히 크더라도 실제 요청 전체의 지연과 자원 사용이 개선되는지 확인한 뒤 적용합니다.

공식 문서와 적용 범위

문서의 기본값과 동작은 version에 따라 달라질 수 있습니다. 현재 JDK/JVM version, 실행 옵션, collector, runtime 환경과 실제 memory 사용 패턴에서 다시 확인합니다.