일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 포트폴리오
- 일정관리프로젝트
- Join
- 데이터 베이스
- 연습문제
- 일정관리 프로젝트
- LV02
- Kafka
- LV0
- GIT
- JPA
- S3
- 프로그래머스
- LV.02
- SQL
- LV01
- 디자인 패턴
- Java
- docker
- 알고리즘
- 코테
- Redis
- LV1
- CI/CD
- spring boot
- Lv.0
- mysql
- LV03
- CoffiesVol.02
- 이것이 자바다
- Today
- Total
코드 저장소.
String vs StringBuilder vs StringBuffer 본문
목차
1.String
2.StringBuilder
3.StringBuffer
4.성능 실험
5.후기
1.String
우선 String은 아래와 같은 특징을 가지고 있습니다.
1-1.불변객체
String은 한 번 생성되면 내부 값을 바꿀 수 없음.
"abc" + "d" → 기존 객체 수정 X , 새로운 객체 생성 O
1-2.문자열 상수 풀
String 리터럴은 Heap 영역의 String Pool에 저장됨.
동일한 리터럴을 재사용하여 메모리를 절약.
String a = "hello";
String b = "hello";
System.out.println(a == b); // true
String c = new String("hello");
System.out.println(a == c); // false
new String("hello")는 Pool을 무시하고 새로운 객체를 생성
1-3.메모리 구조
JDK 8까지: 내부적으로 char[]로 문자 저장.
JDK 9부터: 메모리 최적화를 위해 byte[] + coder 플래그로 저장. (Compact Strings)
→ 영어 같은 Latin-1 문자는 1바이트, 한글은 2바이트 차지.
1-4.String의 장점
불변성 → 스레드 안전, 보안성 높음
상수 풀 덕에 메모리 절약
2.StringBuilder
StringBuilder는 아래와 같은 특징을 가지고 있습니다.
2-1. 가변 객체
String과는 다르게 한 번 생성된 후에도 내부 값을 자유롭게 수정 가능.
StringBuilder sb = new StringBuilder("hello");
sb.append(" world");
System.out.println(sb.toString()); // hello world
2-2. 동작 방식
내부적으로 char[] 버퍼를 사용하며, 문자열 조작 시 기존 버퍼를 수정.
버퍼가 가득 차면 자동으로 확장됨.
2-3. 동기화 미지원
멀티스레드 환경에서는 안전하지 않음.
여러 스레드가 동시에 접근하면 예기치 못한 결과 발생 가능.
2-4. StringBuilder의 장점
문자열 수정/연산 속도가 매우 빠름
메서드 체이닝(append(), insert(), delete())으로 가독성 높음
단일 스레드 환경에서 문자열 조작에 최적화
3.StringBuffer
StringBuffer는 아래와 같은 특징을 가지고 있습니다.
3-1. 가변 객체
StringBuilder와 동일하게 문자열을 수정할 수 있음.
StringBuffer sb = new StringBuffer("hello");
sb.append(" world");
System.out.println(sb.toString()); // hello world
3-2. 동작 방식
내부 구조는 StringBuilder와 동일하지만, 모든 메서드에 synchronized 키워드가 붙어 있음.
→ 멀티스레드 환경에서도 안전하게 동작.
3-3. 동기화 지원
동기화를 제공하지만, 그만큼 불필요한 성능 오버헤드가 존재.
단일 스레드 환경에서는 성능이 StringBuilder보다 떨어짐.
3-4. StringBuffer의 장점
멀티스레드 환경에서 안전하게 문자열 수정 가능
오래된 레거시 코드나 동기화가 필수적인 상황에서 여전히 사용됨
4.성능 실험
그럼 이 셋의 처리속도를 테스트를 해보기 위해서 간단한 실험을 해보겠습니다.
코드는 아래와 같습니다.
public class Main {
private static final int ITERATION = 1000000;
public static void main(String[] args) {
testString();
testStringBuffer();
testStringBuilder();
}
private static void testString() {
long start = System.nanoTime();
String str = "";
for (int i = 0; i < ITERATION; i++) {
str += "a"; // 매번 새로운 객체 생성
}
long end = System.nanoTime();
System.out.println("String: " + (end - start) / 1_000_000 + " ms");
}
private static void testStringBuilder() {
long start = System.nanoTime();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ITERATION; i++) {
sb.append("a");
}
long end = System.nanoTime();
System.out.println("StringBuilder: " + (end - start) / 1_000_000 + " ms");
}
private static void testStringBuffer() {
long start = System.nanoTime();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < ITERATION; i++) {
sb.append("a");
}
long end = System.nanoTime();
System.out.println("StringBuffer: " + (end - start) / 1_000_000 + " ms");
}
}
각각의 방법으로 1000000 수만큼 반복을 해서 처리를 하는 속도를 측정을 해보기로 했고 결과는 아래와 같이 나왔습니다.
결과 해석
- String: 불변 객체이기 때문에 += 할 때마다 새로운 객체를 생성 → 반복 횟수가 늘어날수록 성능이 기하급수적으로 떨어짐.
- StringBuffer: 내부 버퍼를 사용하여 빠른 조작이 가능하지만, 모든 메서드가 synchronized 처리되어 있어 Builder보다 다소 느림.
- StringBuilder: 동기화 처리가 없어서 가장 빠름. 단일 스레드 환경에서 문자열 결합 시 최적.
결론
- 단순 상수 문자열 → String
- 단일 스레드에서 문자열 조립/가공 → StringBuilder
- 멀티 스레드 환경에서 동기화 필요 → StringBuffer
5.후기
이번에 String, StringBuilder, StringBuffer를 직접 성능 비교해보면서, 문법으로만 배웠던 “String은 불변이라서 느리다”라는 말이 숫자로 체감이 되었습니다. 단순히 책에서 읽는 것과 실제로 1,000,000번 돌려본 결과를 보는 건 확실히 다르더군요.
특히 StringBuilder와 StringBuffer의 차이는 생각보다 크지 않았는데, 멀티스레드 환경 여부에 따라 선택 기준이 명확해진다는 걸 알 수 있었습니다.
앞으로는 “무조건 StringBuilder가 빠르다”가 아니라, “상황에 따라 어떤 걸 써야 하는지”를 먼저 생각해야겠다는 걸 배웠습니다.
'Java' 카테고리의 다른 글
== vs equals(), hashCode() (0) | 2025.09.06 |
---|---|
Exception 처리 (Checked vs Unchecked) (0) | 2025.09.06 |
GraalVM? (0) | 2025.08.05 |
객체 비교를 위한 Comparator , Comparable (0) | 2025.02.06 |
JVM 내부구조와 동작원리 (0) | 2024.05.02 |