출력에서 문자열을 합쳐야하는 경우에 나는 성능에 좋다고
들었기 때문에
StringBuilder
를 주로 썼다.
그냥 듣기만 하고 제대로 알아보지 않고 쓸 수는 없지!🚫🚫
과연 성능 상의 이점이 정말 있는지 자세히 알아보려고 한다!
String nice = "nice";
String to = " to";
String meet = " meet";
String greeting = nice + to + meet;
String
+ String
의 경우, nice에 to를 추가하고.. 거기에 meet을 추가하고.. 의 구조가 아니라!
기존 문자열 + 다른 문자열인 새로운 문자열 객체를 만들고 그 객체를 참조하게 하는 것이다.
즉, 아래와 같이 2번의 객체 생성이 일어나는 것이다.
- nice + to = "nice to"
- nice to + meet = "nice to meet"
이렇게 + 마다 메모리에 새로운 문자열로 할당된다면, 어떤 문제가 있을까?
위와 같은 추가 작업들이 누적되면서 성능에 영향을 미치게 되는 것이다.
프로그램이 메모리 관리를 하는 과정 중 하나로,
더 이상 사용되지 않는 메모리를 식별하고 해제하여 메모리 리소스를 절약하고자 하는 프로세스를 말한다!
불변이었던 String
에 반해 StringBuilder는
변경이 가능하다!
StringBuilder greeting = new StringBuilder();
greeting.append("nice").append("to").append("meet");
즉, 문자열을 한 번 만들고나서 다른 문자열을 더할 때,
새로운 객체를 만드는 것이 아니라 기존에 만든 문자열에 추가되는 형식이다.
따라서, 더할 때마다 새로운 객체를 생성하지도 않고
가비지 컬렉션의 작업이 필요하지도 않기때문에 String보다 성능이 좋다고 할 수 있는 것이다!
해당 포스팅에서 성능 비교한 결과가 있어서 발췌해와봤다!
성능을 고려한다면 위와 같이 StringBuilder
가 낫겠지만,
코드의 가독성이나 특정한 상황에서는 String
연산자를 사용하는 것이 더 간편할 수도 있다는 걸 기억해야할 것 같다!
StringBuilder
: 동기화를 보장하지 않음
StringBuffer
: 동기화를 보장함
이라고 하는데 내 수준에서는 구분해서 사용할 정도는 아닌 것 같다😂
일단, 비슷한 기능이고 (동기화가 필요한 경우가 아니라면) 성능면에서 StringBuilder
가 조금 더 낫기 때문에 StringBuilder
를 사용하는 쪽으로 정리하려고 한다!
StringBuilder greeting = new StringBuilder();
greeting.append("nice").append("to").append("meet");
더불어 append()
로 문자열을 합치곤 하는데 이게 메소드 체이닝을 쓰고 있었다는 걸 이번에 알게되었다.
내가 간단히 분석한 결론부터 이야기하면
String.join
은 기존 String
의 문자열 + 방식이 아니라 StringBuilder.append
방식과 유사하게 작동한다고 할 수 있다!
String.join의 내부 메소드
StringBuilder.append의 내부 메소드
좀 더 자세히 들어가봐야겠지만 간단히 분석해보면
아래처럼 String.join
메소드의 내부 구조가 StringBuilder.append
의 구조와 유사한 것을 알 수 있다.
String.join
은 StringBuilder
와 크게 성능차이가 나지 않으니 안심(?)하고 일단은 써도 되겠다.
심층 분석 👍🏻👍🏻
저는 특히 출력시에 반복문을 통해 출력되는 문자를 StringBuilder로 모아서 한번에 출력하는데 자주사용하곤 했는데
IO 낭비 문제 말고도 String 타입보다 성능이 훨 좋네요 👍🏻👍🏻