Go: Build and concatenate strings efficiently

Most of the time

For simple cases where performance is a non-issue, fmt.Sprintf is your friend:

s := fmt.Sprintf("Size: %d MB.", 85) // s == "Size: 85 MB."

The Print with fmt cheat sheet lists the most common formatting verbs and flags.

String builder (Go 1.10)

The strings.Builder type, which will be introduced in Go 1.10, is used to efficiently build a string using write methods.

  • It offers a subset of the bytes.Buffer methods that allows it to safely avoid redundant copying.
  • The Grow method can be used to preallocate memory when the maximum size of the string is known.
var b strings.Builder
b.Grow(16)
b.WriteString("Size: ")
fmt.Fprintf(&b, "%d", 85)
b.WriteString(" MB.")
s := b.String() // No copying!

Before Go 1.10

Use fmt.Fprintf to print into a bytes.Buffer:

var buf bytes.Buffer
for i, p := range []int{2, 3, 5, 7, 11, 13} {
	fmt.Fprintf(&buf, "%d:%d, ", i+1, p)
}
buf.Truncate(buf.Len() - 2) // Remove trailing ", "
s := buf.String()           // s == "1:2, 2:3, 3:5, 4:7, 5:11, 6:13"

This solution is pretty efficient but may generate some excess garbage. For higher performance, you can try to use the append functions in package strconv:

buf := []byte("Size: ")
buf = strconv.AppendInt(buf, 85, 10)
buf = append(buf, " MB."...)
s := string(buf)

If the expected maximum length of the string is known, you may want to preallocate the slice:

buf := make([]byte, 0, 16)
buf = append(buf, "Size: "...)
buf = strconv.AppendInt(buf, 85, 10)
buf = append(buf, " MB."...)
s := string(buf)

Comments

Be the first to comment!