4 ms·
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
by costco 3y ago
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)
- icholy 3y agoYou can clean up this code by writing a package for generating JSON token by token. w := jsonx.New(os.Stdout) w.OpenObject() w.ObjectKey("commit") w.Int(0) w.CloseObject()
- kiitos 3y agoBe careful that you're not pooling buffers of wildly different sizes Also this code has many many problems please never use it to encode JSON :)
- costco 3y agoIt's part of an API client I made for Resy so there are some guarantees on what characters will be in configID which is why I don't escape everything. I actually have a separate pool but I used bytebufferpool.Get instead of client.pool.Get when writing it here so the intent was clearer. But the code has gotten me Friday 7 PM reservations at Tatiana so it works though it's probably overkill because network latency is by far the biggest cost in terms of time. I probably should just have a JSON encoder write to the buffer.