Как изменяется емкость StringBuilder? - PullRequest
5 голосов
/ 25 сентября 2011

Когда у меня есть пустой StringBuilder емкостью 5, и я пишу "привет, мир!"к этому стандарт C # определяет новую емкость StringBuilder?У меня смутное воспоминание, что это вдвое больше длины новой строки (чтобы не менять емкость с каждой новой добавленной строкой).

Ответы [ 3 ]

15 голосов
/ 25 сентября 2011

Зависит от того, о какой версии .NET вы говорите.До .NET 4 StringBuilder использовал стандартную стратегию .NET , удваивая емкость внутреннего буфера каждый раз, когда его нужно увеличивать.

StringBuilder был полностью переписан для .NET 4,теперь используя веревки .Расширение выделения теперь выполняется путем добавления еще одного куска веревки до 8000 символов.Не так эффективно, как в предыдущей стратегии, но позволяет избежать проблем с большими буферами, забивающими кучу больших объектов.Исходный код доступен из справочного источника, если вы хотите поближе.

5 голосов
/ 25 сентября 2011

Стандарт C # не будет определять поведение класса библиотеки BCL, поскольку он не имеет ничего общего со спецификацией языка.

Насколько я знаю, фактическое поведение не определено ни в одной спецификации и зависит от реализации.

AFAIK, реализация MS удвоит емкость, как только будет достигнута текущая емкость.

См. это и это предыдущие SO вопросы.


Обновление:

Это было изменено в .NET 4.0. как описано Гансом в его ответе . Теперь используются веревки , добавляя дополнительно 8000 символов за раз.

MSDN , однако очень осторожно указывает, что фактическое поведение зависит от реализации :

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

0 голосов
/ 18 мая 2017

Новый 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

...