Когда у меня пустой StringBuilder
вместимостью 5 и я пишу "привет, мир!" к нему, определяет ли стандарт C # новую емкость StringBuilder
? Я смутно помню, что это вдвое больше новой длины строки (чтобы избежать изменения емкости с каждой новой добавленной строкой).
Как меняется емкость StringBuilder?
Ответы (3)
Зависит от того, о какой версии .NET вы говорите. До .NET 4 StringBuilder использовал тег стандартная стратегия .NET, удваивающая емкость внутреннего буфера каждый раз, когда его нужно увеличивать.
StringBuilder был полностью переписан для .NET 4, теперь с использованием веревок. Расширение выделения теперь выполняется путем добавления еще одного отрезка веревки длиной до 8000 символов. Не так эффективен, как предыдущая стратегия, но позволяет избежать проблем с большими буферами, засоряющими кучу больших объектов. Исходный код доступен в Справочном источнике, если вы хотите познакомиться с ним поближе.
Стандарт C # не будет определять поведение класса библиотеки BCL, поскольку он не имеет ничего общего со спецификацией языка.
Насколько мне известно, фактическое поведение не определено ни в одной спецификации и зависит от реализации.
AFAIK, реализация MS удвоит емкость, как только будет достигнута текущая емкость.
См. this и это предыдущие вопросы SO.
Обновлять:
Это было изменено в .NET 4.0. как описано Гансом в его ответ. Теперь используются веревки, добавляя дополнительные 8000 символов за раз.
MSDN, однако очень осторожно указывает выяснили, что реальное поведение зависит от реализации:
StringBuilder динамически выделяет больше места, когда это необходимо, и соответственно увеличивает емкость. По соображениям производительности StringBuilder может выделять больше памяти, чем необходимо. Объем выделяемой памяти зависит от реализации.
Новый StringBuilder (.NET 4.5 или выше) выделяет внутренний буфер m_ChunkChars
, запрошенный параметром емкости:
public StringBuilder(int capacity)
{
...
m_ChunkChars = new char[capacity];
...
}
Таким образом, если емкость меньше 40 КБ, она попадает в кучу малых объектов. Однако (вопреки распространенному мнению) StringBuilder по-прежнему будет выделять память в куче больших объектов, если позже мы вызовем sb.Append(...some string larger than 40K chars...);
. Возможное исправление можно найти здесь: https://github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder