Java 반복문 안 문자열 더하기, StringBuilder가 필요한 이유
문제 발생
큰 목록을 문자열로 합치는 코드에서 반복 횟수가 늘어날수록 실행 시간이 비선형으로 증가하는 경우가 있습니다.
String result = "";
for (String item : items) {
result += item; // 반복마다 새 String 객체 생성
}원인 분석
Java의 String은 불변(immutable) 객체입니다. result += item은 실제로는 result = result + item이고, 매번 새로운 String 객체를 만들어 이전 내용을 전부 복사한 뒤 새 내용을 이어 붙입니다. 반복이 n번이면 총 복사량이 1+2+...+n에 비례해 O(n²)이 됩니다.
컴파일러가 단일 표현식 안의 + 연산은 내부적으로 StringBuilder로 최적화해주지만, 반복문에 걸친 +=는 최적화 대상이 아닙니다 — 매 반복마다 새 StringBuilder가 생성되고 즉시 toString()으로 변환되는 것과 같습니다.
해결 방안
반복문 밖에서 StringBuilder를 하나 만들고 반복 안에서는 append()만 호출합니다. StringBuilder는 내부적으로 크기가 가변인 char 배열을 유지하며, 필요할 때만 배열을 키우기 때문에 전체 연산이 O(n)에 가깝습니다.
StringBuilder sb = new StringBuilder();
for (String item : items) {
sb.append(item);
}
String result = sb.toString();초기 용량을 대략 예상할 수 있다면 new StringBuilder(expectedSize)로 생성해 배열 재할당 횟수를 줄일 수 있습니다. 멀티스레드 환경에서 여러 스레드가 같은 버퍼에 동시에 쓴다면 StringBuilder가 아니라 동기화된 StringBuffer를 써야 합니다 — 다만 대부분의 경우 스레드마다 별도 버퍼를 쓰는 편이 더 낫습니다.
공식 문서
짧은 반복(수십 회 이하)이라면 체감 차이가 거의 없으므로, 실제로 느린 지점인지 프로파일링으로 먼저 확인하고 최적화합니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.