← Назад к вопросам

В чем разница между String и StringBuilder?

2.0 Middle🔥 101 комментариев
#Коллекции и структуры данных

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между String и StringBuilder в C#

String и StringBuilder — это два принципиально разных класса в C# для работы со строками, которые имеют фундаментальные различия в архитектуре, поведении и сфере применения.

Основное концептуальное отличие

String является неизменяемым (immutable) типом, в то время как StringBuilderизменяемым (mutable).

Когда вы создаете объект string, его значение не может быть изменено после создания. Любая операция, которая кажется изменяющей строку (конкатенация, замена подстроки и т.д.), на самом деле создает новый объект в памяти. Это приводит к накладным расходам на выделение памяти и сборку мусора.

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

Ключевые технические различия

Производительность при множественных операциях:

// Медленный вариант со String (создается 5 объектов!)
string result = "";
for (int i = 0; i < 10000; i++) {
    result += i.ToString(); // Каждое сложение создает новый объект
}

// Быстрый вариант со StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.Append(i.ToString()); // Работает с одним буфером
}
string finalResult = sb.ToString();

Поведение при модификации:

  • String: Все методы возвращают новые строки
  • StringBuilder: Методы изменяют текущий экземпляр и возвращают его же (часто через this)

Семантика использования:

  • String — для статических или редко изменяемых данных
  • StringBuilder — для динамического построения строк

Память и производительность

String:

  • Каждая модификация создает новую копию в куче (heap)
  • Высокие накладные расходы при частых изменениях
  • Оптимизация компилятора для простых конкатенаций (но не в циклах!)

StringBuilder:

  • Имеет внутренний буфер (по умолчанию 16 символов)
  • Автоматически увеличивает емкость при необходимости
  • Минимальные аллокации при работе

Синтаксис и методы

// String методы
string text = "Hello";
text = text.Replace("H", "J"); // Создает новую строку
text = text + " World"; // Создает новую строку

// StringBuilder методы
StringBuilder sb = new StringBuilder("Hello");
sb.Replace("H", "J"); // Изменяет существующий буфер
sb.Append(" World"); // Добавляет к существующему буферу

Когда что использовать

Используйте String, когда:

  • Строки редко изменяются или не изменяются вовсе
  • Вы работаете с константными значениями
  • Нужна безопасность потоков (strings immutable, поэтому потокобезопасны)
  • Используете строки как ключи в словарях
  • Выполняете единичные операции конкатенации

Используйте StringBuilder, когда:

  • Необходимо много раз модифицировать строку (особенно в циклах)
  • Строите сложные строки из множества частей
  • Работаете с большими объемами текстовых данных
  • Важна производительность при построении строк

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

StringBuilder внутри использует массив символов (char[]), который динамически расширяется. При превышении емкости создается новый массив большего размера (обычно в 2 раза) и копируются данные из старого:

// Пример внутренней логики увеличения емкости
public StringBuilder Append(string value) {
    if (value != null) {
        // Проверка, хватит ли места в буфере
        // Если нет - увеличение буфера
        // Копирование новых символов
    }
    return this;
}

Важные нюансы

  1. StringBuilder не всегда быстрее — для простых операций или малого числа конкатенаций разница может быть незаметна или даже в пользу String.

  2. Оптимизации компилятора — компилятор C# иногда заменяет конкатенации строк на вызовы String.Concat, что может быть эффективнее.

  3. Инициализация емкости — если известно примерное количество символов, лучше сразу задать емкость StringBuilder:

StringBuilder sb = new StringBuilder(estimatedCapacity);
  1. ToString() — метод ToString() у StringBuilder создает новую строку, копируя содержимое буфера.

Выводы

Основное правило: используйте String для "статичных" строк, StringBuilder для "динамического построения" строк. Выбор между ними часто является компромиссом между удобством использования и производительностью. Для большинства сценариев, где строки не меняются часто, String является оптимальным выбором благодаря своей простоте и безопасности. Для сценариев, где строки активно модифицируются (особенно в циклах), StringBuilder обеспечивает существенный прирост производительности.