Skip to content

Conversation

@zjumathcode
Copy link

Description

strings.Builder has fewer memory allocations and better performance.
More info: golang/go#75190

Rationale

tell us why we need these changes...

Example

add an example CLI or API response...

Changes

Notable changes:

  • add each change in a bullet point here
  • ...

@zjumathcode
Copy link
Author

I wrote a benchmark that shows the performance advantage of using strings.Builder, as follows:

package bench_test

import (
	"fmt"
	"strings"
	"testing"
)

type Route struct {
	Group          string
	MatcherSetsRaw string
	HandlersRaw    []string
	Terminal       bool
}

func (r Route) StringOld() string {
	handlersRaw := "["
	for _, hr := range r.HandlersRaw {
		handlersRaw += " " + string(hr)
	}
	handlersRaw += "]"

	return fmt.Sprintf(`{Group:"%s" MatcherSetsRaw:%s HandlersRaw:%s Terminal:%t}`,
		r.Group, r.MatcherSetsRaw, handlersRaw, r.Terminal)
}

func (r Route) StringNew() string {
	var handlersRaw strings.Builder
	handlersRaw.WriteString("[")
	for _, hr := range r.HandlersRaw {
		handlersRaw.WriteString(" " + string(hr))
	}
	handlersRaw.WriteString("]")

	return fmt.Sprintf(`{Group:"%s" MatcherSetsRaw:%s HandlersRaw:%s Terminal:%t}`,
		r.Group, r.MatcherSetsRaw, handlersRaw.String(), r.Terminal)
}

func BenchmarkRouteString_Old(b *testing.B) {
	r := Route{
		Group:          "api",
		MatcherSetsRaw: "[matcher]",
		HandlersRaw:    []string{"foo", "bar", "baz", "qux", "quux"},
		Terminal:       true,
	}
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		_ = r.StringOld()
	}
}

func BenchmarkRouteString_New(b *testing.B) {
	r := Route{
		Group:          "api",
		MatcherSetsRaw: "[matcher]",
		HandlersRaw:    []string{"foo", "bar", "baz", "qux", "quux"},
		Terminal:       true,
	}
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		_ = r.StringNew()
	}
}
➜  benchmark go test -bench=. -benchmem
goos: darwin
goarch: arm64
pkg: demo/stringsbuilder/benchmark
cpu: Apple M4
BenchmarkRouteString_Old-10      5239779               211.3 ns/op           248 B/op         10 allocs/op
BenchmarkRouteString_New-10      6258066               193.5 ns/op           200 B/op          7 allocs/op
PASS
ok      demo/stringsbuilder/benchmark 3.482s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant