Closed
Description
Sometimes, I find myself wanting to join a slice of strings and append the result to a strings.Builder
. This can be done by:
- Use something like
Builder.WriteString(strings.Join([]string{"foo", "bar"}, ", "))
, less coding, but results in 1 extra allocation. - Write my own joining loop against the builder, basically duplication of code of the current
strings.Join
function.
Currently, strings.Join()
already uses a strings.Builder
. This issue proposes to move the code from this function into a method of strings.Builder
. The current strings.Join()
function will become a wrapper which allocates a new builder and calls this new method for further processing.
Example (adjusted copy of strings.Join()
):
type Builder struct {
strings.Builder
}
func (b *Builder) Join(elems []string, sep string) {
switch len(elems) {
case 0:
return
case 1:
b.Grow(len(elems[0]))
b.WriteString(elems[0])
}
n := len(sep) * (len(elems) - 1)
for i := 0; i < len(elems); i++ {
n += len(elems[i])
}
b.Grow(n)
b.WriteString(elems[0])
for _, s := range elems[1:] {
b.WriteString(sep)
b.WriteString(s)
}
}
Benchmarks code:
func Benchmark_Builder_Join(b *testing.B) {
for i := 0; i < b.N; i++ {
var b Builder
b.Join([]string{"Hello", "World!"}, ", ")
}
}
func Benchmark_Join_and_WriteString(b *testing.B) {
for i := 0; i < b.N; i++ {
var b Builder
b.WriteString(
strings.Join([]string{"Hello", "World!"}, ", "),
)
}
}
Benchmark run:
go test -benchmem -bench .
goos: linux
goarch: amd64
pkg: github.com/muhlemmer/pbpgx
cpu: AMD Ryzen 9 5900HX with Radeon Graphics
Benchmark_Builder_Join-16 30865467 72.17 ns/op 16 B/op 1 allocs/op
Benchmark_Join_and_WriteString-16 19650562 138.8 ns/op 32 B/op 2 allocs/op
PASS
ok github.com/muhlemmer/pbpgx 5.132s
Items open for discussion:
- Name of the method (
Join
,AppendJoin
orWriteJoin
?). - Should the method return total bytes written, as returned by
WriteString()
? - Should the method return
error
, as returned byWriteString()
? (Is alwaysnil
)
Related: PR #42850, which got put on hold for not going trough the proposal process (and duplicates code)