Skip to content

refactor: use strings.Builder to improve performance#7364

Merged
francislavoie merged 2 commits intocaddyserver:masterfrom
zjumathcode:master
Feb 16, 2026
Merged

refactor: use strings.Builder to improve performance#7364
francislavoie merged 2 commits intocaddyserver:masterfrom
zjumathcode:master

Conversation

@zjumathcode
Copy link
Contributor

Assistance Disclosure

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

@CLAassistant
Copy link

CLAassistant commented Nov 25, 2025

CLA assistant check
All committers have signed the CLA.

@vnxme
Copy link
Contributor

vnxme commented Nov 25, 2025

Interested to see any tests showing how much the performance gain is, if any, in ns per request or requests per second.

@zjumathcode
Copy link
Contributor Author

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

package caddy_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

@vnxme
Copy link
Contributor

vnxme commented Dec 5, 2025

@zjumathcode Thanks, so you have an 8% gain in ns/op, a 19% decrease in B/op and a 30% drop in allocs/op in your benchmark which is quite good. Does your PR cover all the places in the code where strings are concatenated?

@boqishan
Copy link

@zjumathcode Thanks, so you have an 8% gain in ns/op, a 19% decrease in B/op and a 30% drop in allocs/op in your benchmark which is quite good. Does your PR cover all the places in the code where strings are concatenated?

This is a generic performance improvement plan, based on suggestions and support from the Go team.

More info: golang/go#75190.

zjumathcode and others added 2 commits February 16, 2026 14:24
Signed-off-by: zjumathcode <pai314159@2980.com>
…ites)

also revert builder change in client_test.go

refactor(logging): build IP mask output via join of parts (more efficient)
@francislavoie
Copy link
Member

The PR had fallen inactive so I went ahead and fixed up the remainder as per review comments.

@francislavoie francislavoie added the optimization 📉 Performance or cost improvements label Feb 16, 2026
@francislavoie francislavoie added this to the v2.11.0 milestone Feb 16, 2026
@francislavoie francislavoie enabled auto-merge (squash) February 16, 2026 19:29
@francislavoie francislavoie merged commit 68d5002 into caddyserver:master Feb 16, 2026
29 checks passed
This was referenced Feb 20, 2026
@francislavoie francislavoie mentioned this pull request Feb 20, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

optimization 📉 Performance or cost improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants