Nice practical article. I tried to rewrite the code in it to use byte slices and calls to the bytes package instead of strings while keeping the calls to Split, thinking it would be faster due to less copying. The allocations were actually about 1.5x higher than in the original string version. It turns out a slice header in Go is 24 bytes versus 16 for a string header, and 24/16 = 1.5.
Tangentially related:
Not really necessary here but lately I've been using buffer pools like the one by the fasthttp author to avoid allocating in performance sensitive places. But the code is sometimes pretty ugly.
// get buffer from pool
body := bytebufferpool.Get()
// create request body
body.WriteString(`{"config_id":"`)
for i := range configID {
c := configID[i]
if c != '/' {
body.WriteByte(c)
} else {
// escape slash
body.WriteByte('\\')
body.WriteByte('/')
}
}
body.WriteString(`","commit":`)
if commit {
body.WriteByte('1')
} else {
body.WriteByte('0')
}
body.WriteString(`,"struct_items":[]}`)
// send request
...
// add back to pool
bytebufferpool.Put(body)