728x90
반응형
1. 🚨 문제 상황 (Issue)
프로그래머스의 '숫자 짝꿍' 문제를 풀면서 알고리즘의 시간 복잡도를 $O(N)$으로 최적화했음에도 불구하고 반복문 내에서 데이터를 처리할 때 시간 초과(Time Out)가 발생했다.
당시 문제가 되었던 코드 조각은 다음과 같다.
Java
// 시간 초과의 주범
for (int i = zzak_arr.length - 1; i >= 0; i--) {
int cc = zzak_arr[i];
for (int j = 0; j < cc; j++) {
answer += i; // ❌ 반복문 안에서 String에 + 연산 누적
}
}
2. 🔍 원인 분석: String의 불변성 (Immutability)
자바에서 String 객체는 한 번 생성되면 값을 변경할 수 없는 불변(Immutable) 객체다.
따라서 answer += i; 코드가 실행될 때 기존 문자열 뒤에 숫자가 단순히 붙는 것이 아니다. 내부적으로는 매번 새로운 메모리 공간을 할당받아 새로운 String 객체를 만들고, 기존 내용을 복사하는 과정이 일어난다.
- 이 문제에서 입력값 $X, Y$의 길이는 최대 3,000,000(3백만)이다.
- 즉, 최악의 경우 문자열 복사 및 새 객체 생성 행위를 수백만 번 반복하게 된다.
- 이로 인해 메모리 낭비(Garbage Collection 유발)와 심각한 시간 지연이 발생해 시간 초과로 이어진 것이다.
3. 🚀 해결책: StringBuilder 사용하기
문자열을 빈번하게 수정, 추가해야 할 때는 값이 변할 수 있는(Mutable) 클래스인 StringBuilder를 사용해야 한다.
💻 수정된 코드
Java
// 1. StringBuilder 객체 생성
StringBuilder sb = new StringBuilder();
for (int i = zzak_arr.length - 1; i >= 0; i--) {
int cc = zzak_arr[i];
for (int j = 0; j < cc; j++) {
if (i != 0) zero_check = 0;
// 2. append() 메서드로 뒤에 문자를 가볍게 붙여줌
sb.append(i);
}
}
// 3. 최종 출력을 위해 String으로 변환
String answer = sb.toString();
4. ❓ StringBuilder는 왜 더 빠를까? (원리)
StringBuilder는 내부에 문자를 저장하는 가변 크기의 배열(char[] 또는 byte[])을 버퍼로 가지고 있다.
- 메모리 재사용: append()를 호출할 때 새 객체를 매번 만드는 것이 아니라, 내부에 있는 배열의 값만 바꾼다. (마치 자바스크립트의 array.push()처럼 동작)
- 효율적인 확장: 배열의 공간이 부족해질 때만 내부적으로 배열의 크기를 키우기 때문에, 객체 생성 횟수가 극적으로 줄어든다.
결과적으로 객체 생성 오버헤드가 사라져 수백만 번의 연산도 단 몇 밀리초(ms) 만에 끝낼 수 있게 된다.
5. 📊 핵심 요약 (String vs StringBuilder 전후 비교)
| 특징 | String | StringBuilder |
| 가변성 | 불변 (Immutable) | 가변 (Mutable) |
| 연산 방식 | 연산 시마다 새로운 객체 생성 | 기존 버퍼(배열)에 값 추가 |
| 적합한 상황 | 문자열 연산이 적고 조회가 많을 때 | 반복문 내에서 문자열 추가/수정이 잦을 때 |
| 성능 (이번 문제) | ❌ 시간 초과 (Fail) | ⭕ 수 밀리초 만에 통과 (Pass) |
반응형
'Study' 카테고리의 다른 글
| [내일배움캠프 TIL] Terraform으로 AWS EC2 배포 자동화 완성 (0) | 2026.06.22 |
|---|---|
| [내일배움캠프 TIL] Testcontainers와 Karate DSL로 구축하는 MSA 테스트 환경 (통합 테스트 vs E2E 테스트) (0) | 2026.06.19 |
| [내일배움캠프 TIL] REST API에서 현재 로그인 유저를 표현하는 방법 - /me vs /{userId} (0) | 2026.06.12 |
| [내일배움캠프 TIL] Spring Cloud Config Server 설정 파일 관리 방식: Native vs Git 분리 (우리의 선택과 기술적 명분) (0) | 2026.06.11 |
| [내일배움캠프 TIL] 마이크로서비스(MSA) 간 통신 방법 총정리 (0) | 2026.06.10 |