Gemini와 만담(?)하며 알고리즘을 풀다보면 StringBuilder라는 친구가 심상찮게 등장한다.
자료형이 자유형에 가까운 파이썬으로 알고리즘을 하던 나였기에.. String과 StringBuilder, 그리고 StringBuffer는 어떻게 다른걸까?
잘 정리된 글은 이미 많으니, 지금 지식 수준에서 이해한만큼만 정리해보자
우선, 셋 다 문자열을 표현하는 클래스(Reference Type)다.
다만, String의 경우 자주 사용되기에 기본 자료형(Primitive Type: int, double 등) 처럼 리터럴 방식으로 선언이 가능하다.
String str = "abc";
그러면, 왜 다를까? 우선, String과 StringBuilder, StringBuffer의 차이점부터 보자.
불변(mutable) vs 가변(mutable)
String은 불변 자료형이고, StringBuilder와 StringBuffer는 가변 자료형이다.
즉, String 객체의 값은 변경할 수 없다.
가능하다. 하지만 원본 객체의 값이 변하는 것이 아닌 더해진 새로운 객체를 참조하는 방법으로 실행된다.
이때 기존 객체의 값은 Garbage Collector(GC)의 제거 대상이 된다.
String str = "hello"; // 2. 기존 "hello" 객체 GC 제거 대상
str += " world"; // 1. 새로운 "hello world" 객체 생성 및 참조 변경
System.out.println(str); // hello world
이에 비해 StringBuilder 혹은 StringBuffer의 경우 '+' 대신 append()로 객체를 직접 변경할 수 있다.
StringBuilder sb = new StringBuilder();
sb.append("hello");
sb.append(" world");
System.out.println(sb); // hello world
알아야 할 차이점과 동작에 대한 내용이 더 있겠지만, 지금 수준에선
StringBuffer (혹은 StringBuilder)String정도로 기억해도 무방하다.
그럼 이제, StringBuffer와 StringBuilder는 어떻게 다를까?
이 둘은 가변적 특성을 갖고 있고, 제공 메서드와 활용 방법이 완전히 동일하다.
둘 사이의 차이는 단 하나
멀티 쓰레드(Thread)에서 안전(safe)한가?
StringBuffer 클래스는 쓰레드에서 안전하고 (thread safe)
StringBuilder 클래스는 쓰레드에서 안전하지 않다 (thread unsafe)
이 차이는 동기화(Synchronization) 지원 유무에 의해 발생하는데, StringBuffer만 동기화를 지원해 멀티 스레드 환경에서 안전한 동작이 가능하다.
아직 본인이 쓰레드에 대한 학습이 부족해, 이 부분에 대해서는 간단하게만 알아보자.
우선 성능을 비교하자면 싱글 쓰레드 환경에서, 문자열 연산 속도를 비교하면 StringBuilder가 StringBuffer보다 빠르다고 한다.
하지만 이 차이는 String 사용에 비하면 그렇게까지 의미 있는 큰 차이는 아니라고 볼 수 있다
자, 일단 문자열 변경이 많은 경우라서 String을 제외한 시점에서 둘 중에 뭘 써야 한다고 하면,
StringBuilder대부분의 알고리즘 환경은 싱글 쓰레드에서 실행되며, 시간 단축이 중요하기 때문에 StringBuilder를 쓴다. (그래서 AI들이 다들 builder만 썼나보다.)
여기는 내가 알지 못하는 영역이지만, 이에 관한 몇 가지 관점이 있는듯 했다.
StringBuffer로 작업을 한다.혹은
StringBuilder로 동기화 비용을 아끼고, 클래스의 멤버 변수로 선언되어 여러 쓰레드가 공유하는 경우에만 StringBuffer를 선택한다.둘 다 이해가 가는 관점인지라, 일단은 차이점만 인지하고, 알고리즘에서는 StringBuilder를 열심히 쓰기로 한다.
[Inpa Dev 👨💻] 자바 String / StringBuffer / StringBuilder 차이점 & 성능 비교
쓰레드(Thread) 동기화(Synchronization)