String의 경우, 새로운 문자열을 생성할 때마다 String Constant Pool에 저장해두고 가져다 쓴다.
때문에, 변하지 않는 문자열을 자주 읽는 경우엔 좋은 성능을 기대할 수 있다.
하지만, 문자열 추가, 수정, 삭제 등의 연산이 빈번하다면 힙 메모리에 많은 임시 가비지가 생성되어 성능에 영향을 준다.
반면에, StringBuilder는 내부에 Buffer라는 데이터를 임시로 저장하는 메모리가 있고, 여기에 문자열을 저장해둔다.
그리고 Buffer 안에서 추가, 수정, 삭제 작업을 할 수 있도록 설계되어 있다.
그래서 동일 객체 내에서 문자열 크기를 변경하는 것이 가능하다.
문자열 연산의 종류
1.
+ 연산자
2.
String.concat 메서드
3.
StringBuffer
4.
StringBuilder
String str = "hello ";
1. String a = str + "world"; // 앞서 + 연산은 자동으로 StringBuilder로 변환된다고 말했다.
2. String b = str.concat("world");
3. String c = new StringBuffer("hello").append("world").toString();
4. String d = new StringBuilder("hello").append("world").toString();
Java
복사
•
+ 연산의 경우 JDK 1.4 이후로 StringBuilder 객체를 생성해서 컴파일 시점에 최적화
◦
반복문과 같은 곳에선 StringBuilder 객체를 생서하고 변수에 대입하는 과정이 계속 일어나 성능상 좋지 않다.
•
String.concat 의 경우 원본 문자열의 매번 배열을 재구성 하는 과정을 거치기 때문에 느림
•
StringBuffer 혹은 StringBuilder의 경우 초기에 Buffer 크기를 정해놓고 시작하기 때문에 String.concat 보다 연산의 결과가 빠르다.
◦
단, 무조건 적으로 빠른 것은 아니다. 초기 Buffer 크기는 문자열 수정 시 늘어났다가 줄어들었다를 반복하므로 많은 양의 문자열 수정이라면 내부 연산의 시간이 많이 걸린다.
String | StringBuffer | StringBuilder | |
가변 여부 | 불변 | 가변 | 가변 |
Thread Safe | O | O | X |
연산 속도 | 느림 | 빠름 | 아주 빠름 |
사용 시점 | 문자열 추가 연산 적고, Thread Safe한 환경 | 문자열 추가 연산 많고, Thread Safe한 환경 | 문자열 추가 연산 많고, 빠른 연산이 필요하며 단일 Thread인 경우 |