JAVA/Effective Java

[아이템 63] 문자열 연결은 느리니 주의하라

꾸준함. 2024. 3. 17. 19:24

문자열 연결 연산자(+)는 여러 문자열을 하나로 결합해주는 편리한 도구입니다.

주로 한 줄로 된 출력값이나 고정 크기의 객체의 문자열 표현을 만들 때 사용하기에 유용합니다.

  • ex) `String fullName = this.firstName + this.lastName;`

 

하지만 문자열 연결 연산자로 문자열 N개를 잇는 시간 복잡도는 O(N^2)이기 때문에 본격적으로 많은 문자열을 합치기 시작하면 성능 저하를 피하기 어렵습니다.

  • 문자열은 불변이기 때문에 두 문자열을 연결하는 경우 양쪽의 내용을 복사하여 연결한 다음 새로운 String 객체를 생성해야하기 때문
  • 성능을 포기하고 싶지 않다면 String 대신 StringBuilder를 사용하는 것을 권장
  • 자바 6번 이후 문자열 연결 성능을 다방면으로 개선했지만, 두 메서드의 성능 차이는 여전히 큼

 

 

 

String vs StringBuffer vs StringBuilder

 

1. String

 

  • 불변(Immutable) 클래스이기 때문에 한 번 생성된 문자열은 변경할 수 없음
  • 문자열에 대한 연산이 수행될 때마다 새로운 문자열 객체가 생성됨
  • 멀티쓰레드 환경에서 thread-safe
  • 주로 문자열에 대한 변화가 없는 경우나, 변경된 문자열을 새로 생성하는 것이 아닐 때 사용
  • String의 concat 연산은 + 기호를 사용

 

2. StringBuffer

 

  • 가변(Mutable) 클래스이며 문자열 변경 가능
  • 문자열의 추가, 삽입, 삭제 등의 연산을 수행할 때 유용
  • 멀티 쓰레드 환경에서 동기화되어 있어 thread-safe
    • append 메서드에 synchronized 키워드가 적용되어 있기 때문에 한 쓰레드가 작업 진행 시 락 걸림 
    • 이 때문에 단일 쓰레드 환경에서는 StringBuilder보다 조금 느릴 수 있음

 

 

3. StringBuilder

 

  • StringBuffer와 유사하지만, thread-safe하지 않음
  • 단일 쓰레드 환경에서 StringBuffer보다 더 빠르게 동작
    • 동기화에 대한 오버헤드가 없으므로 StringBuffer보다 메모리 사용이 적음
    • 단일 쓰레드 환경에서 문자열을 동적으로 조작할 때 주로 사용

 

  • 하지만 각 StringBuilder 인스턴스를 하나의 쓰레드만 수정할 수 있다는 것을 보장하는 경우 StringBuilder를 사용하는 것이 더 효율적 (https://stackoverflow.com/questions/26860173/what-does-stringbuilders-are-not-thread-safe-mean )
    • 대부분 문자열을 여러 개의 스레드를 공유하지 않고 StringBuilder/StringBuffer를 로컬 변수로 사용하여 순차적으로 구성하기 때문에 StringBuffer보다는 StringBuilder 사용을 권장

 

참고

이펙티브 자바

반응형