В чём разница между string и StringBuilder


В языке программирования C# и других языках платформы .NET string и StringBuilder используются для работы с текстовыми данными, но имеют принципиально разные характеристики и области применения.

📌 string — неизменяемый (immutable) тип

Класс string представляет собой последовательность символов Unicode, но при этом является неизменяемым. Это означает, что после создания строки её содержимое нельзя изменить. Любая операция, которая «изменяет» строку, на самом деле создаёт новый объект в памяти.

🔹 Примеры:

string s = "Hello";
s += " World"; // создается новая строка, а не изменяется существующая

В этом примере создается новая строка "Hello World", и переменная s указывает уже на другой объект. Старая строка "Hello" остается в памяти до тех пор, пока её не соберёт сборщик мусора.

📌 StringBuilder — изменяемый (mutable) тип

Класс StringBuilder предназначен для эффективного построения и модификации строк. Его экземпляры можно изменять без создания новых объектов в памяти. Это особенно полезно при многократных операциях добавления, вставки, удаления и замены строк.

🔹 Примеры:

StringBuilder sb = new StringBuilder("Hello");
sb.Append(" World"); // объект sb изменяется на месте

Здесь объект sb сохраняется в памяти, и в него добавляется текст " World". Новые строки в памяти не создаются при каждом вызове Append.

📊 Сравнение string и StringBuilder

Свойство string StringBuilder
Изменяемость Неизменяемый Изменяемый
--- --- ---
Производительность Медленная при множественных изменениях Высокая при множественных изменениях
--- --- ---
Выделение памяти Новый объект при каждом изменении Один объект в памяти
--- --- ---
Поддержка операций +, +=, Insert, Replace и др. Append, Insert, Replace, Remove и др.
--- --- ---
Удобство Удобен для небольших строк и редких операций Эффективен при сложных манипуляциях
--- --- ---
Потокобезопасность Потокобезопасен (неизменяемый объект) Не потокобезопасен без синхронизации
--- --- ---
Использование в выражениях Удобен и читаем Менее читаем при простых операциях
--- --- ---
Член System.String или System.Text System.String System.Text.StringBuilder
--- --- ---

📦 Где лучше использовать string

  • Когда строка не изменяется после создания.

  • При небольшом числе операций объединения (например, в логике if или return).

  • Когда важна простота и читаемость.

string greeting = "Hello" + " " + "World";

🚀 Где лучше использовать StringBuilder

  • При многократных изменениях строки (добавление, удаление, замена).

  • При построении больших строк (например, генерация HTML, SQL, логов).

  • В циклах, где объединяются строки.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
sb.Append("Line " + i + "\\n");
}
string result = sb.ToString();

Если бы вместо StringBuilder использовался string, то на каждой итерации создавался бы новый объект — это бы резко увеличило расход памяти и снизило производительность.

📚 Внутреннее устройство StringBuilder

  • Использует буфер символов внутри.

  • При необходимости буфер расширяется.

  • Изменения происходят на месте, без копирования всего содержимого при каждом изменении.

Пример создания с заданной ёмкостью:

StringBuilder sb = new StringBuilder(capacity: 100);

Это уменьшает количество перераспределений памяти при больших объёмах данных.

⚠️ Потенциальные подводные камни

  • StringBuilder не потокобезопасен, если используется из нескольких потоков — нужно использовать блокировки.

  • Избыточное использование StringBuilder для простых строк делает код громоздким.

  • При слишком больших буферах, особенно при частом создании StringBuilder, может быть перерасход памяти.

🧪 Тест производительности

// string
string s = "";
for (int i = 0; i < 10000; i++)
{
s += i.ToString();
}
// StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.Append(i);
}

Во втором случае StringBuilder отработает в десятки раз быстрее, особенно при большом числе итераций, потому что не создаёт новый объект строки на каждой итерации.

Таким образом, string и StringBuilder решают одну и ту же задачу — работу с текстом — но подходят для разных ситуаций: string — для простоты и читаемости, StringBuilder — для эффективности и производительности.