Skip to content

Commit

Permalink
Avoid an additional allocation for the encoding
Browse files Browse the repository at this point in the history
We can pre-allocate a large-enough buffer, and then in-place encode the bits to avoid
the allocation done by hex.EncodeToString().

Effectively this shaves a couple of ns off the generation:
  • Loading branch information
ankon committed Oct 21, 2024
1 parent 40efd0b commit ce4def8
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions v3/internal/trace_id_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package internal

import (
"encoding/hex"
"math/rand"
"sync"
)
Expand Down Expand Up @@ -39,6 +38,10 @@ const (
maxIDByteLen = 16
)

const (
hextable = "0123456789abcdef"
)

// GenerateTraceID creates a new trace identifier, which is a 32 character hex string.
func (tg *TraceIDGenerator) GenerateTraceID() string {
return tg.generateID(traceIDByteLen)
Expand All @@ -50,9 +53,15 @@ func (tg *TraceIDGenerator) GenerateSpanID() string {
}

func (tg *TraceIDGenerator) generateID(len int) string {
var bits [maxIDByteLen]byte
var bits [maxIDByteLen * 2]byte
tg.Lock()
defer tg.Unlock()
tg.rnd.Read(bits[:len])
return hex.EncodeToString(bits[:len])

// In-place encode
for i := len - 1; i >= 0; i-- {
bits[i*2+1] = hextable[bits[i]&0x0f]
bits[i*2] = hextable[bits[i]>>4]
}
return string(bits[:len*2])
}

0 comments on commit ce4def8

Please sign in to comment.