Когда использовать string?
- Для коротких строк (до 10-15 конкатенаций)
- Когда строка не изменяется после создания
- Для константных значений и литералов
- В однопоточных сценариях без частых модификаций
string greeting = "Hello";
string name = "John";
string message = greeting + " " + name + "!"; // Простая конкатенация
Когда использовать StringBuilder?
- Множественные модификации строки (более 10-15 операций)
- Большие строки или сложные преобразования
- Циклы с конкатенацией строк
- Высокопроизводительные сценарии
var sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.Append(i).Append(", ");
}
string result = sb.ToString();
Как работает StringBuilder?
Внутренняя структура:
-
Буфер символов (char array):
- Начинается с емкости по умолчанию (16 символов в .NET Core)
- Динамически расширяется при необходимости
-
Механизм роста:
- При заполнении буфера создается новый массив (обычно в 2 раза больше)
- Существующие символы копируются в новый массив
- Старый массив становится доступным для GC
Ключевые особенности:
-
Изменяемость:
- В отличие от string, StringBuilder мутабелен
- Операции модификации работают с тем же объектом
-
Методы для эффективной работы:
- Append(), Insert(), Remove(), Replace()
- Поддержка цепочки вызовов (Fluent API)
-
Управление емкостью:
- Можно задать начальную емкость
- Можно уменьшить емкость до фактического размера
// Оптимизация с предустановленной емкостью
var sb = new StringBuilder(initialCapacity: 1024);
Производительность
Сравнение операций :
Операция | string (мс) | StringBuilder (мс) |
Конкатенация в цикле | 15-20 | 0.1-0.3 |
Многократный Append | N/A | 0.1-0.5 |
Память:
- string: создает новый объект при каждой операции
- StringBuilder: минимизирует аллокации за счет буфера
Лучшие практики
-
Задавайте начальную емкость, если знаете примерный размер:
new StringBuilder(estimatedLength);
-
Используйте Clear() для повторного использования:
sb.Clear().Append("New content");
-
Избегайте избыточных ToString():
// Плохо:
sb.Append(someStringBuilder.ToString());
// Хорошо:
sb.Append(someStringBuilder);
-
Для простых сценариев используйте интерполяцию строк:
string message = $"{greeting} {name}!"; // Компилятор оптимизирует
Как работает под капотом?
-
Append:
- Проверяет достаточно ли места в буфере
- При необходимости увеличивает буфер
- Копирует новые символы в буфер
-
ToString:
- Создает новый string из текущего буфера
- Если емкость равна длине, использует текущий буфер
Резюмируем:
используйте string для простых и неизменяемых строк, StringBuilder — для сложных или часто изменяемых строковых операций. StringBuilder обеспечивает лучшую производительность за счет уменьшения количества аллокаций памяти и оптимизированных операций с буфером.