Strings.Builder
Often programs must append many strings to form a single, larger string
. This can cause some performance issues.
With a special type in Go, we can append strings faster. Fewer allocations are needed. The appends are performed faster. The strings.Builder
type is used here.
Here we create a new strings.Builder
. Please note that Go 1.10 or later is required to run this program. A compile-time error occurs on earlier versions.
WriteString
func
appends the argument string
to the strings.Builder
instance.String()
method converts the buffered data in the Builder into a Go string
.package main import ( "fmt" "strings" ) func main() { // Create new Builder. builder := strings.Builder{} // Write a string 5 times. for i := 0; i < 5; i++ { builder.WriteString("bird ") } // Convert Builder to String and print it. result := builder.String() fmt.Println(result) }bird bird bird bird bird
To pass the strings.Builder
to another func
, and have that func
call WriteString
to add to the builder, we can pass a reference to the strings.Builder
.
package main import ( "fmt" "strings" ) func Append2Strings(builder *strings.Builder) { builder.WriteString("ABC") builder.WriteString("XYZ") } func main() { builder := strings.Builder{} // Pass as reference to use it in another method. Append2Strings(&builder) fmt.Println(builder.String()) }ABCXYZ
This is an important performance optimization for strings.Builder
in Go programs. If we know an approximate size of the entire data, we can use a capacity.
Grow()
to accommodate the entire length of the final data. Fewer resizes will be required.Grow()
can lead to measurable performance improvements in real-world programs.package main import ( "fmt" "strings" ) func main() { builder := strings.Builder{} // Grow to a larger size to reduce future resizes of the buffer. builder.Grow(30000) builder.WriteString("Test") fmt.Println(builder.String()) }Test
Why should we use strings.Builder
instead of string
appends? The answer is performance. We can append strings faster with a strings.Builder
.
strings.Builder
and calls WriteString
many times.string
with the plus operator. This code causes allocations.string
data to a strings.Builder
than use strings.package main import ( "fmt" "strings" "time" ) func main() { t0 := time.Now() // Version 1: use Builder with WriteString. for i := 0; i < 100000; i++ { builder := strings.Builder{} for v := 0; v < 100; v++ { builder.WriteString("hello") } if builder.Len() == 0 { break } } t1 := time.Now() // Version 2: use string appends. for i := 0; i < 100000; i++ { result := "" for v := 0; v < 100; v++ { result += "hello" } if len(result) == 0 { break } } t2 := time.Now() // Results. fmt.Println(t1.Sub(t0)) fmt.Println(t2.Sub(t1)) }142.232646ms strings.Builder 1.234626415s string +=
With strings.Builder
and WriteString()
we see an early 10x speedup in a simple benchmark. This type can improve the performance of many programs.