[공부한 것] String보다 StringBuilder를 써야할까? + String.join은 어떨까?

별의개발자커비·2023년 10월 30일
3

우테코 도전기

목록 보기
22/37

개요

출력에서 문자열을 합쳐야하는 경우에 나는 성능에 좋다고 들었기 때문에 StringBuilder를 주로 썼다.
그냥 듣기만 하고 제대로 알아보지 않고 쓸 수는 없지!🚫🚫
과연 성능 상의 이점이 정말 있는지 자세히 알아보려고 한다!


1. String + String

문자열 추가 구조

String nice = "nice";
String to = " to";
String meet = " meet";
String greeting = nice + to + meet;

String + String의 경우, nice에 to를 추가하고.. 거기에 meet을 추가하고.. 의 구조가 아니라!

기존 문자열 + 다른 문자열인 새로운 문자열 객체를 만들고 그 객체를 참조하게 하는 것이다.
즉, 아래와 같이 2번의 객체 생성이 일어나는 것이다.

  1. nice + to = "nice to"
  2. nice to + meet = "nice to meet"

이렇게 + 마다 메모리에 새로운 문자열로 할당된다면, 어떤 문제가 있을까?

성능 상의 문제점

  1. 각 연결 단계에서 새로운 문자열 객체 생성
    • 객체 생성마다 메모리 할당 및 문자열 복사 작업이 일어나게 된다.
  2. 가비지 컬렉션
    • 이러게 연결 단계마다 새로운 문자열이 생성되면, 이전에 생성된 문자열은 필요하지 않게된다.
      위에서는 "nice to"라는 문자열은 더 이상 필요하지 않기때문에
      가비지 컬렉션은 이와 같은 중간 문자열을 해제하는 작업을 하게된다.

위와 같은 추가 작업들이 누적되면서 성능에 영향을 미치게 되는 것이다.

잠깐, 가비지 컬렉션이란?

프로그램이 메모리 관리를 하는 과정 중 하나로,
더 이상 사용되지 않는 메모리를 식별하고 해제하여 메모리 리소스를 절약하고자 하는 프로세스를 말한다!


2. StringBuilder.append()

문자열 추가 구조

불변이었던 String에 반해 StringBuilder는 변경이 가능하다!

StringBuilder greeting = new StringBuilder();
greeting.append("nice").append("to").append("meet");

즉, 문자열을 한 번 만들고나서 다른 문자열을 더할 때,
새로운 객체를 만드는 것이 아니라 기존에 만든 문자열에 추가되는 형식이다.

따라서, 더할 때마다 새로운 객체를 생성하지도 않고
가비지 컬렉션의 작업이 필요하지도 않기때문에 String보다 성능이 좋다고 할 수 있는 것이다!


🔎 성능 비교

해당 포스팅에서 성능 비교한 결과가 있어서 발췌해와봤다!


🔎 그럼 StringBuilder이 항상 좋은걸까?

성능을 고려한다면 위와 같이 StringBuilder가 낫겠지만,
코드의 가독성이나 특정한 상황에서는 String 연산자를 사용하는 것이 더 간편할 수도 있다는 걸 기억해야할 것 같다!


🔎 StringBuilder vs StringBuffer?

StringBuilder: 동기화를 보장하지 않음
StringBuffer: 동기화를 보장함

이라고 하는데 내 수준에서는 구분해서 사용할 정도는 아닌 것 같다😂
일단, 비슷한 기능이고 (동기화가 필요한 경우가 아니라면) 성능면에서 StringBuilder가 조금 더 낫기 때문에 StringBuilder를 사용하는 쪽으로 정리하려고 한다!

참고) 메소드 체이닝?

StringBuilder greeting = new StringBuilder();
greeting.append("nice").append("to").append("meet");

더불어 append()로 문자열을 합치곤 하는데 이게 메소드 체이닝을 쓰고 있었다는 걸 이번에 알게되었다.

  • 메소드 체이닝이란?
    연속해서 메소드를 호출하는 것, 코드가 간결해져서 가독성이 좋아진다!

참고한 글 : 자바 String, StringBuilder 그리고 StringBuffer 성능 차이 비교


🔎 번외) 그럼 String.join은?

내가 간단히 분석한 결론부터 이야기하면
String.join은 기존 String의 문자열 + 방식이 아니라 StringBuilder.append 방식과 유사하게 작동한다고 할 수 있다!

String.join의 내부 메소드

StringBuilder.append의 내부 메소드

좀 더 자세히 들어가봐야겠지만 간단히 분석해보면
아래처럼 String.join 메소드의 내부 구조가 StringBuilder.append의 구조와 유사한 것을 알 수 있다.

결론 (나 혼자 결론 주의🚨)

String.joinStringBuilder와 크게 성능차이가 나지 않으니 안심(?)하고 일단은 써도 되겠다.

2개의 댓글

comment-user-thumbnail
2023년 11월 5일

심층 분석 👍🏻👍🏻
저는 특히 출력시에 반복문을 통해 출력되는 문자를 StringBuilder로 모아서 한번에 출력하는데 자주사용하곤 했는데
IO 낭비 문제 말고도 String 타입보다 성능이 훨 좋네요 👍🏻👍🏻

1개의 답글