Skip to content

Optimize string concatenation#22

Open
JohnAkindipe wants to merge 1 commit into
BiniWorld:binibftfrom
JohnAkindipe:modernize-string-concatenation
Open

Optimize string concatenation#22
JohnAkindipe wants to merge 1 commit into
BiniWorld:binibftfrom
JohnAkindipe:modernize-string-concatenation

Conversation

@JohnAkindipe

Copy link
Copy Markdown

perf: replace string concatenation with strings.Builder in makeStatsdFormat

Overview

makeStatsdFormat in consensus/pkg/api/metrics.go previously built its return
value by repeatedly concatenating onto a string variable inside a loop:

// Before
for _, s := range labelNames {
    str += fmt.Sprintf(".%%{%s}", s)
}
return str

This has been replaced with a strings.Builder-based implementation:

// After
var sb strings.Builder
sb.WriteString(str)
for _, s := range labelNames {
    fmt.Fprintf(&sb, ".%%{%s}", s)
}
return sb.String()

Why string concatenation is inefficient

Strings in Go are immutable. Every += on a string does not append in-place,
instead it allocates memory for a new string, copies the old string over into the new
memory location and then appends the content. This happens for every append
operation. Essentially, it leads to more memory usage and puts pressure on the
garbage collector to clean up unused memory.


Why strings.Builder is better

strings.Builder maintains an internal byte buffer and is useful to efficiently
build a string and minimize memory copying.


Benchmark results

Benchmarks were run with -benchmem -count=3 on an Intel Core i3-1005G1 @ 1.20 GHz
(Go 1.26.2, linux/amd64).

goos: linux
goarch: amd64
pkg: github.com/hyperledger/binibft-poc/consensus/pkg/api
cpu: Intel(R) Core(TM) i3-1005G1 CPU @ 1.20GHz

BenchmarkMakeStatsdFormatOld-4   648640   1964 ns/op   696 B/op   24 allocs/op
BenchmarkMakeStatsdFormatOld-4   602698   1922 ns/op   696 B/op   24 allocs/op
BenchmarkMakeStatsdFormatOld-4   492110   2334 ns/op   696 B/op   24 allocs/op

BenchmarkMakeStatsdFormatNew-4   807993   1390 ns/op   400 B/op   13 allocs/op
BenchmarkMakeStatsdFormatNew-4   746988   1525 ns/op   400 B/op   13 allocs/op
BenchmarkMakeStatsdFormatNew-4   888039   1355 ns/op   400 B/op   13 allocs/op

Summary

Metric Old (concat) New (Builder) Improvement
ns/op ~2,073 ~1,423 ~31% faster
B/op 696 400 ~43% less memory
allocs/op 24 13 ~46% fewer allocations

Files changed

File Change
consensus/pkg/api/metrics.go Replaced loop body in makeStatsdFormat with strings.Builder

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