C# StringBuilder

2022년 06월 23일
제작기간 2022년 06월 23일
태그 csharp

String을 여러 번 수정해야할 때, StringBuilder를 쓰는 것이 효율적이다. 그 이유를 정리한다.

String Builder는 문자열을 변경하는 용도로 사용할 수 있는 Class이다.

using System.Text;

// String Builder
var currentWorkingSet = Environment.WorkingSet;
var current = Environment.TickCount;
StringBuilder sb = new();
for (int i = 0; i < 10000; i++)
{
    sb.Append(i.ToString());
}
var sbString = sb.ToString();
Console.WriteLine($"String builder: {Environment.TickCount - current} milliseconds");
Console.WriteLine(Environment.WorkingSet - currentWorkingSet);


// String Adding
currentWorkingSet = Environment.WorkingSet;
current = Environment.TickCount;
string str = "";
for (int i = 0; i < 10000; i++)
{
    str += i.ToString();
}
Console.WriteLine($"String Add: {Environment.TickCount - current} milliseconds");
Console.WriteLine(Environment.WorkingSet - currentWorkingSet);

Console.WriteLine($"Is same string: {sbString.Equals(str)}");

// Outputs
// String builder: 1 milliseconds
// 2744320
// String Add: 33 milliseconds
// 4407296
// Is same string: True

두 방식은 시간과 메모리 사용량 모두 차이를 보인다. String은 값 타입이며, 값 타입은 값을 수정할 시에 새로 데이터를 할당한다. String을 반복해서 더하는 방식은 매번 String 타입의 데이터를 생성한다.

StringChecker();

unsafe void StringChecker()
{
    string value = "first";
    fixed (char* start = value)
    {
        value = String.Concat(value, "Second");
        fixed (char* current = value)
        {
            Console.WriteLine($"Concat result: {start == current}");
        }
    }

    fixed (char* start = value)
    {
        value += "Third";
        fixed (char* current = value)
        {
            Console.WriteLine($"Adding result: {start == current}");
        }
    }
}
// Output
// Concat result: False
// Adding result: False
  • Tip: unsafe를 run하기 위해선 .csproj에 아래 구문을 추가해주어야 함.
  <PropertyGroup>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

StringBuilder는 이러한 문제를 방지하고 반복문 안에서 효과적으로 string 연산을 수행할 수 있다.

기본으로 16자를 용량으로 가지고 있으며, 용량을 초과할 시 List와 같은 방식으로 2배씩 늘어난다. 최초에 초기 용량을 지정할 수 있으며, 배수하여 늘어나는 최대 길이는 2 billion(21억) 정도다.