Search code examples
stringgostringbuilder

Why doesn’t string.Builder Reset() preserve the underlying buffer?


// Reset resets the Builder to be empty.
func (b *Builder) Reset() {
    b.addr = nil
    b.buf = nil
}

The code snippet is from the source code in go strings.Builder. The buffer is set to nil instead of b.buf[:0]. What would be a reason to set it to nil instead of preserving the capacity?

EDIT: I can see that Reset() can be used to GC the underlying buffer and allow the Builder struct to be re-used, but it seems like a marginal cost to initialize the struct since it is just two pointers, whereas the underlying array might have been much bigger, and could've been re-used. I feel like there should have been a Clear() function that kept the underlying buffer's capacity but reduced its length to 0, and it would have been trivial to implement. This leads me to believe there is a reason as to why that was not done, and I am curious as to what that reason is.


Solution

  • One of the optimisation of strings.Builder is that it doesn't copy bytes when converting []byte to string. Take a look at it's String() method:

    // String returns the accumulated string.
    func (b *Builder) String() string {
        return *(*string)(unsafe.Pointer(&b.buf))
    }
    

    It means that reusing the buffer would destroy previously created strings.

    And here is the proof on the playground: https://play.golang.org/p/gkSXRwi0-Ff