StringBuilder的容量如何变化?

当我有一个容量为5的空StringBuilder时,我写了“你好,世界!” 对它来说,C#标准是否指定了StringBuilder的新容量? 我有一个模糊的记忆,它是新字符串长度的两倍(以避免每个新附加字符串改变容量)。

取决于您正在谈论的.NET版本。 在.NET 4之前,StringBuilder使用标准的.NET策略 ,每次需要扩大时,内部缓冲区的容量就会翻倍。

StringBuilder完全被重写为.NET 4,现在使用绳索 。 现在通过添加另一条最多8000个字符的绳索来扩展分配。 不像早期策略那样有效,但避免了大缓冲区堵塞大对象堆的麻烦。 如果您想仔细查看,可以从参考源获得源代码。

C#标准不会指定BCL库类的行为,因为它与语言规范无关。

据我所知,实际行为未在任何规范中定义,并且是特定于实现的。

AFAIK,一旦达到当前容量,MS实施将使容量翻倍。

看到这个和之前的SO问题。


更新:

这已在.NET 4.0中更改。 正如汉斯在回答中所描述的那样。 现在使用绳索 ,一次添加额外的8000个字符。

但是, MSDN非常谨慎地指出实际行为是特定于实现的

StringBuilder在需要时动态分配更多空间,并相应地增加容量。 出于性能原因,StringBuilder可能会分配比所需更多的内存。 分配的内存量是特定于实现的。

新的StringBuilder(.NET 4.5或更高版本)分配capacity参数请求的内部缓冲区m_ChunkChars

public StringBuilder(int capacity) { ... m_ChunkChars = new char[capacity]; ... }

因此,如果容量小于40K字符,那么它就会出现在小对象堆上。 然而(与流行的看法相反),如果稍后我们调用sb.Append(...some string larger than 40K chars...); ),StringBuilder仍会分配大对象堆sb.Append(...some string larger than 40K chars...); 可以在这里找到一个可能的修复: https : //github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder