StringBuilder的容量如何变化?
当我有一个容量为 5 的空 StringBuilder
时,我写下“hello, world!”对此,C# 标准是否指定了 StringBuilder 的新容量?我有一个模糊的记忆,它是新字符串长度的两倍(以避免每个新附加字符串改变容量)。
When I have an empty StringBuilder
with a capacity of 5 and I write "hello, world!" to it, does the C# standard specify the new capacity of the StringBuilder
? I have a vague memory that it's twice the new string's length (to avoid changing the capacity with every new appended string).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
取决于您所讨论的 .NET 版本。在 .NET 4 之前,StringBuilder 使用 标准.NET策略,每次需要扩大内部缓冲区的容量时将其容量加倍。
StringBuilder 已针对 .NET 4 完全重写,现在使用 绳索。现在可以通过添加另一根最多 8000 个字符的绳子来扩展分配。效率不如早期策略,但避免了大缓冲区堵塞大对象堆的问题。如果您想仔细查看,可以从参考源获取源代码。
Depends what version of .NET you're talking about. Prior to .NET 4, StringBuilder used the standard .NET strategy, doubling the capacity of the internal buffer every time it needs to be enlarged.
StringBuilder was completely rewritten for .NET 4, now using ropes. Extending the allocation is now done by adding another piece of rope of up to 8000 chars. Not quite as efficient as the earlier strategy but avoids trouble with big buffers clogging up the Large Object Heap. Source code is available from the Reference Source if you want to take a closer look.
C# 标准不会指定 BCL 库类的行为,因为它与语言规范无关。
据我所知,实际行为没有在任何规范中定义,并且是特定于实现的。
AFAIK,一旦达到当前容量,MS 的实施将使容量加倍。
请参阅此和这个以前的SO问题。
更新:
这已在 .NET 4.0 中更改。正如 Hans 在 他的答案。现在使用绳索,一次添加额外的 8000 个字符。
MSDN,但是非常小心地指出实际行为是特定于实现的:
The C# standard will not specify the behavior of a BCL library class as it has nothing to do with the language specification.
As far as I know the actual behavior is not defined in any specification and is implementation specific.
AFAIK, The MS implementation will double the capacity once the current capacity has been reached.
See this and this previous SO questions.
Update:
This has been changed in .NET 4.0. as described by Hans in his answer. Now ropes are used, adding additional 8000 characters at a time.
MSDN, however is very careful to point out that the actual behavior is implementation specific:
新的 StringBuilder(.NET 4.5 或更高版本)分配容量参数请求的内部缓冲区
m_ChunkChars
:public StringBuilder(intcapacity)
{
...
m_ChunkChars = new char[容量];
...
因此
,如果容量小于 40K 字符,它将位于小对象堆上。然而(与普遍的看法相反),如果稍后我们调用 sb.Append(...some string more than 40K chars...);,StringBuilder 仍将在大对象堆上分配可以在这里找到修复:
https://github.com/amikunov/Large -Object-Heap-Fix-For-.NET-String-Builder
New StringBuilder (.NET 4.5 or higher) allocates an internal buffer
m_ChunkChars
requested by the capacity parameter:public StringBuilder(int capacity)
{
...
m_ChunkChars = new char[capacity];
...
}
So, if capacity is smaller than 40K chars it goes on the Small Object Heap. However (contrary to popular belief), StringBuilder will still allocate on the Large Object Heap if, later, we call
sb.Append(...some string larger than 40K chars...);
A possible fix can be found here:https://github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder