핵심 차이점: 가변성(Mutability)
두 클래스의 가장 큰 차이는 StringBuilder는 가변(mutable)이라는 점이고, String은 불변(immutable)이라는 점입니다.
String — 불변(Immutable)
String은 불변 객체입니다. 즉, 문자열 객체를 한 번 생성하면 그 값을 수정할 수 없으며, 문자열을 변경하는 모든 연산은 메모리에 새로운 string 객체를 생성하게 됩니다. 따라서 잦은 문자열 수정 작업에서는 불필요한 객체가 계속 만들어져 성능 저하와 메모리 낭비로 이어질 수 있습니다.
StringBuilder — 가변(Mutable)
반면 StringBuilder는 가변 객체입니다. StringBuilder 객체를 생성한 후에는 매번 새 인스턴스를 만들 필요 없이 삽입(insert), 교체(replace), 추가(append) 같은 연산을 자유롭게 수행할 수 있습니다. 메모리 내 동일한 위치에서 문자열을 직접 갱신하므로 새로운 메모리 공간을 할당하지 않아 성능 면에서 훨씬 효율적입니다.
예제 코드
using System;
using System.Text;
class DemoApplication{
public static void Main(String[] args){
String systemString = "Hello";
StringConcat(systemString);
Console.WriteLine("String Class Result: " + systemString);
StringBuilder stringBuilderString = new StringBuilder("Hello");
StringBuilderConcat(stringBuilderString);
Console.WriteLine("StringBuilder Class Result: " + stringBuilderString);
}
public static void StringConcat(String systemString){
String appendString = " World";
systemString = String.Concat(systemString, appendString);
}
public static void StringBuilderConcat(StringBuilder stringBuilderString){
stringBuilderString.Append(" World");
}
}실행 결과
위 예제의 출력 결과는 다음과 같습니다.
String Class Result: Hello StringBuilder Class Result: Hello World
코드 분석
StringConcat 메서드: 이 메서드는 "Hello"라는 문자열을 전달받아
systemString = String.Concat(systemString, appendString);를 통해 " World"를 연결하려고 시도합니다. 그러나 Main()에서 전달된 원본 문자열은 변경되지 않습니다. 그 이유는 String이 불변(immutable)이기 때문입니다. 문자열 값을 변경하려는 시도는 새로운 객체를 생성하며, StringConcat() 내부의 systemString 변수는 새 문자열에 대한 참조만 저장합니다. 결국 Main()의 systemString과 StringConcat()의 systemString은 서로 다른 문자열 객체를 가리키게 됩니다.StringBuilderConcat 메서드: 이 메서드는 "Hello"라는 문자열을 전달받아
stringBuilderString.Append(" World");를 수행하며, Main()에 있는 실제 문자열 값을 "Hello World"로 변경합니다. 이는 StringBuilder가 가변(mutable)이기 때문에 가능한 동작입니다.
그렇다면 어떤 것을 사용해야 할까?
선택 기준은 문자열 조작 빈도에 따라 달라집니다.
- StringBuilder를 권장하는 경우: 루프 안에서 문자열을 반복적으로 연결하거나, 대량의 텍스트를 조립·수정하는 작업. 새 객체 생성 오버헤드가 없어 성능이 크게 향상됩니다.
- String을 권장하는 경우: 단순한 문자열 연결, 값이 거의 변하지 않는 데이터, 스레드 간 안전한 공유가 필요한 경우. String은 불변이므로 별도의 동기화 없이도 안전하게 사용할 수 있습니다.
결론적으로, 두 클래스 중 어느 쪽이 '더 낫다'기보다는 용도에 맞게 선택하는 것이 올바른 접근입니다. 반복적인 문자열 수정이 많다면 StringBuilder, 일반적인 문자열 처리라면 String을 사용하는 것이 C# 개발의 모범 사례입니다.