4

I know that the StringBuilder object allocates more memory when you use sb.Append(..) when the sb is already at capacity. But how much does that capacity increase?

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

Now what is the capacity of sb and why? What is the multiplier?

Just for clarity. I am asking about capacity and not length.

Thanks!

Nick
  • 19,198
  • 51
  • 185
  • 312

2 Answers2

7

The capacity doubles each time apart from some special cases:

  • If doubling is not enough then the capacity is further increased to the exact amount that is required.
  • There is an upper limit - 0x7fffffff.

You can see the algorithm by using .NET Reflector or downloading the reference source.

I can't post the source code for the official .NET implementation but here's the code for the Mono implementation:

// 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;
}

I would also recommend that you don't write code that relies on this specific algorithm as it is an implementation detail, and not something that is guaranteed by the interface.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • Didn't Reflector start charging? :) – Nick Dec 21 '10 at 02:46
  • 1
    @Nick only the pro version (which is well worth the cost, FYI) – Rex M Dec 21 '10 at 02:49
  • 2
    @Mark: Please do not post framework code obtained with Reflector. Aside from this being a copyright violation, this is a problem for those of us working on other .NET runtimes, where [clean-room reimplementation is required](http://www.mono-project.com/Contributing). – cdhowie Dec 21 '10 at 02:51
  • 1
    @Mark: Thanks. I'm sure Mono's StringBuilder implementation is pretty much complete by now, and therefore the code won't hurt too much, but I just wanted to point this out for future reference. – cdhowie Dec 21 '10 at 02:57
  • @cdhowie: Is it legal to post the Mono implementation instead? – Mark Byers Dec 21 '10 at 03:00
  • 1
    @Mark: Absolutely. Mono's implementations of the framework libraries are made available under the terms of the MIT license, which is pretty close to "do whatever you want with this." [Here's Mono's implementation](https://github.com/mono/mono/blob/master/mcs/class/corlib/System.Text/StringBuilder.cs). – cdhowie Dec 21 '10 at 03:02
  • 2
    @cdhowie don't mean to be cheeky but I posted a question re. publishing framework code a while ago. You have some interesting thoughts, perhaps you'd like to add to it? http://stackoverflow.com/questions/3109357/is-it-legal-to-make-code-decompiled-from-net-libraries-publicly-available – Tim Lloyd Dec 21 '10 at 03:17
  • @chibacity: The top answer is pretty much spot on. I will add a comment about alternate framework contributors. – cdhowie Dec 21 '10 at 03:19
0

It's exponential growth (specifically, doubling with each reallocation), in order to allow a series of appends to take O(N) time instead of O(N²) time.

dan04
  • 87,747
  • 23
  • 163
  • 198