StringBuilder如何决定其容量的大小?

4

我知道当一个StringBuilder对象已经达到容量限制时,使用sb.Append(..)将会分配更多的内存。但是容量会增加多少呢?

    StringBuilder sb = new StringBuilder(5);
    sb.Append("0123456789");

现在,什么是sb的容量以及为什么?什么是乘数?

只是为了清晰明了。我问的是容量而不是长度。

谢谢!

2个回答

7

除了某些特殊情况外,容量每次翻倍:

  • 如果翻倍不足以满足需求,则进一步增加容量以达到所需精确数量。
  • 有一个上限 - 0x7fffffff。

您可以使用.NET Reflector或下载参考源代码来查看算法。

我无法发布官方.NET实现的源代码,但这是Mono实现的代码:

// Try double buffer, if that doesn't work, set the length as capacity
if (size > capacity) {

    // The first time a string is appended, we just set _cached_str
    // and _str to it. This allows us to do some optimizations.
    // Below, we take this into account.
    if ((object) _cached_str == (object) _str && capacity < constDefaultCapacity)
        capacity = constDefaultCapacity;

    capacity = capacity << 1;  // This means "capacity *= 2;"

    if (size > capacity)
        capacity = size;

    if (capacity >= Int32.MaxValue || capacity < 0)
        capacity = Int32.MaxValue;

    if (capacity > _maxCapacity && size <= _maxCapacity)
        capacity = _maxCapacity;
}

我建议您不要编写依赖于此特定算法的代码,因为它是一种实现细节,而不是接口所保证的内容。

1
@Nick 只有专业版(值得一提的是,它的价格非常划算)。 - Rex M
2
@Mark:请不要发布使用Reflector获取的框架代码。除了这是侵犯版权外,对于我们在其他.NET运行时上工作的人来说,这是一个问题,因为需要进行“清洁室重新实现”。(http://www.mono-project.com/Contributing) - cdhowie
1
@Mark:谢谢。我相信Mono的StringBuilder实现现在已经非常完整了,因此这段代码不会有太大问题,但我只是想为将来提出这个问题。 - cdhowie
1
@Mark:没错。Mono框架库的实现是根据MIT许可证提供的,这与“随心所欲”的要求非常接近。这里是Mono的实现 - cdhowie
2
@cdhowie,不是有意冒犯,但我之前发布了一个关于发布框架代码的问题。您有一些有趣的想法,也许您想要补充一下?http://stackoverflow.com/questions/3109357/is-it-legal-to-make-code-decompiled-from-net-libraries-publicly-available - Tim Lloyd
显示剩余3条评论

0

这是指数级增长(具体来说,每次重新分配都会翻倍),以便允许一系列的附加操作花费O(N)时间而不是O(N²)时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接