[ 개발 잡소리 ] StringBuilder를 사용해보자

2025. 4. 9. 09:29개발잡소리

StringBuilder를 알고 있는가?

StringBuilder는 문자열을 효율적으로 다루기 위한 C# 내장 클래스이다.

간단히 말해서 문자열을 반복적으로 수정하거나 추가할 때에 StringBuilder를 사용하면 성능이 훨씬 좋아진다.


그냥 String을 쓰면 안 되나??

string을 쓰면 안 되는 게 아니다. 일반적인 경우에서는 그냥 string을 넣는 게 맞다.

다만. 몇 가지 경우에 string을 쓰는 것이 엄청난 오버헤드가 발생한다.

 

 

C#에서 string은 불변(immutable) 객체이기 때문에. 기존 문자열을 수정하면, 기존 문자열을 바꾸는 게 아니라

새로운 문자열을 새로 만들고 기존의 문자열은 버리는 식으로 작동한다.

string result = "";
for (int i = 0; i < 1000; i++) {
    result += i.ToString();  // 매번 새로운 문자열을 생성함
}

내부적으로 매 반복마다 새로운 문자열이 생성되는 것이라. 매우 비효율적이라 볼 수 있다.

특히 이 문제는 반복이 많을수록 심각해진다.

 

[ 개발 잡소리 ] 문자열

문자열은 무엇일까간단하게 결론부터 말하자면 문자의 배열이다 그렇다면 그냥 문자만의 배열일까?#include int main() { char str[] = { 'M', 'I','N', 'G' }; std::cout 로 C++코드를 짜보았다 char은 1byte의 문자

dev-vcs.tistory.com

 

 

사실 이건 C#만의 문제가 아니라 현대의 많은 언어들에게서 발생하는 문제이다.

자바와 파이썬의 경우에도 똑같은 문제가 발생한다.

String ming = "";
ming += "a";  // 역시 새 String 객체 생성됨
s = ""
s += "a"  # 새 문자열 객체 생성됨

 


StringBuilder를 쓰면 뭐가 좋은가?

stringBuilder는 내부적으로 문자열 버퍼를 가지고 있다. 따라서 Apped() 함수를 통해 문자열을 수정하면

매번 새로운 문자열을 만드는 것이 아닌 내부의 버퍼를 수정하기 때문에 메모리 오버헤드가 발생하지 않는다.

StringBuilder sb = new StringBuilder();
sb.Append("mmm");

 

 

그럼 혹시

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.Append("mmm");  
}

이런 식으로 코드에서 지정된 문자열을 반복적으로 Append()를 했을 때,

"mmm"은 새로 추가되는 문자열이나 그런 게 아닌 것일까 하는 의문이 있을 수 있다.

 

이는 새롭게 생성된 문자열 객체가 아닌. 문자열 리터럴이다. 리터럴은 런타임이 시작되자마자 자동으로 메모리에 미리 만들어두는 문자열이다. 여기서 Append를 했을 때에 StringBuilder는 그 문자열의 내용을 복사해서 자신의 내부 버퍼에 이를 추가하는 방식으로 동작하기 때문에 큰 문제는 생기지 않는다.

 

C#자체가 Java를 모티브로 만들어진 언어이기 때문에 이러한 문자열 관리 방법이 대체로 유사하다.

관련 내용을 심화적으로 알아보고 싶다면 아래 글을 보는 것을 추천한다. 

 

[ 개발 잡소리 ] HashCode와 String (Java 잡소리)

Java의 System객체에는 IdentifyHashCode()이 있고모든 Object를 상속받은 자료형에는 HashCode()라는 기본함수가 들어있다. 뭐가 다른 걸까?System.IdentifyHashCode()이 녀석이 뭐 하는 놈이냐면 () 안에 들어온 객

dev-vcs.tistory.com

 

C#과 Java를 비교하면 이러하다.

문자열 리터럴 관리 string interning 사용 string interning 사용
문자열 불변성 ✅ string은 immutable ✅ String은 immutable
문자열 비교 (값) == 비교 시 내용 비교 .equals() 사용해야 내용 비교
문자열 비교 (참조) ReferenceEquals() 사용 ==은 참조 비교, .equals()는 값 비교
문자열 조합 최적화 컴파일러가 리터럴 자동 병합 컴파일러가 리터럴 자동 병합
문자열 조합 도구 StringBuilder (mutable) StringBuilder / StringBuffer (mutable)

(굉장히 비슷한 모습을 볼 수 있다.)


정리

요약하자면. StringBuilder는 문자열의 내용이 반복적으로 수정되거나

큰 텍스트를 동적으로 생성시킬 때, 문자열 생성 성능을 최적화할 때 쓰면 된다.