코딩하는 오징어
String vs StringBuffer vs StringBuilder 본문
이 글에서 각 클래스의 사용법을 설명하지는 않겠다. 각 클래스들의 특징과 성능적인 관점에서 비교해보고자 포스팅을 하는 것이기 때문이다.
비교
코드를 먼저 보자.
final String value="abcde"; | |
for (int i = 0; i < 10; i ++) { | |
String str = new String(); | |
StringBuffer strBuffer = new StringBuffer(); | |
StringBuilder strBuilder = new StringBuilder(); | |
for (int j = 0; j < 10000; j++) { | |
str += value; | |
} | |
for (int j = 0; j < 10000; j++) { | |
strBuffer.append(value); | |
} | |
for (int j = 0; j < 10000; j++) { | |
strBuilder.append(value); | |
} | |
} |
더할 값(value)에서 임시로 사용되는 객체가 생성되지 않도록 하기 위해 final String으로 지정하였다. 실행 결과를 살펴보자.
응답시간
주요 소스 부분 |
응답 시간(ms) |
비고 |
str += value |
95,801.41ms |
95초 |
strBuffer.append(value) |
247.48ms |
0.24초 |
strBuilder.append(value) |
174.17ms |
0.17초 |
String 클래스의 문제점이 보이는가?? 이게 끝이아니다.
메모리 사용량
주요 소스 부분 |
메모리 사용량(bytes) |
생성된 임시 객체 수 | 비고 |
str += value |
100,102,000,000 |
4,000,000 | 약 95Gb |
strBuffer.append(value) |
29,493,600 |
1,200 | 약 28Mb |
trBuilder.append(value) |
29,493,600 |
1,200 | 약 28Mb |
응답 시간 String보다 StringBuffer가 약 367배 빠르며, StringBuilder가 약 512배 빠르다. 메모리는 StringBuffer와 StringBuilder보다 String에서 약 3,390배 더 사용한다.이러한 결과가 왜 발생하는지 알아보자.
str += value;
str에 value를 더하면 새로운 String 클래스의 객체가 만들어지고, 이전에 있던 str객체는 필요 없는 쓰레기 값이 되어 GC대상이 된다.
- str += value;
주소 |
값 |
100 |
"abcde" |
- str += value;
주소 |
값 |
150 |
"abcdeabcde" |
- str += value;
주소 |
값 |
200 |
"abcdeabcdeabcde" |
String 클래스를 이용하여 연산하게 된다면 위와 같은 상황이 발상하는 것이다. 연산이 이루어질 때마다 새로운 객체가 생성되고 이전 객체는 GC대상이된다.
- strBuilder.append(value);
주소 |
값 |
100 |
"abcde" |
- strBuilder.append(value);
주소 |
값 |
100 |
"abcdeabcde" |
- strBuilder.append(value);
주소 |
값 |
100 |
"abcdeabcdeabcde" |
StringBuffer나 StringBuilder는 String과는 다르게 새로운 객체를 생성하지 않고, 기존에 있는 객체의 크기를 증가시키면서 값을 더한다. 그럼 위 클래스들은 어느 상황에 쓰이면 좋을까??
- String은 짧은 문자열을 더할 경우 사용한다.
- StringBuffer는 스레드에 안전한 프로그램이 필요할 때나, 개발 중인 시스템의 부분이 스레드에 안전한지 모를 경우 사용하면 좋다.(동기화 됨)
- StringBuilder는 스레드에 안전한지의 여부와 전혀 관계 없는 프로그램을 개발할 때 사용하면 좋다.(동기화가 안됨)
버전에 따른 차이
JDK 5.0이상을 사용한다면 사실 결과가 달라진다. 자바 컴파일러가 문자열을 더하는 코드를 자동으로 StringBuilder의 append함수로 변환 시키기 때문이다.
참고서적 : 자바 성능 튜닝 이야기
'Language > Java' 카테고리의 다른 글
Java에서의 인터럽트 (interrupt) (0) | 2019.05.01 |
---|---|
CompletableFuture Manual (0) | 2019.04.21 |
java 8 Stream이란? (0) | 2018.04.22 |
java 8 람다식이란? (0) | 2018.04.17 |