Skip to content

Commit

Permalink
Avoid one memory allocation in LabelSet construction (#318)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmacd authored and rghetia committed Nov 14, 2019
1 parent 9d19d82 commit ee87858
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions sdk/metric/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type (
// repeatedly.
labels struct {
meter *SDK
sorted []core.KeyValue
sorted sortedLabels
encoded string
}

Expand Down Expand Up @@ -245,39 +245,41 @@ func (m *SDK) Labels(kvs ...core.KeyValue) api.LabelSet {
return &m.empty
}

ls := &labels{
meter: m,
sorted: kvs,
}

// Sort and de-duplicate.
sorted := sortedLabels(kvs)
sort.Stable(&sorted)
sort.Stable(&ls.sorted)
oi := 1
for i := 1; i < len(sorted); i++ {
if sorted[i-1].Key == sorted[i].Key {
sorted[oi-1] = sorted[i]
for i := 1; i < len(ls.sorted); i++ {
if ls.sorted[i-1].Key == ls.sorted[i].Key {
ls.sorted[oi-1] = ls.sorted[i]
continue
}
sorted[oi] = sorted[i]
ls.sorted[oi] = ls.sorted[i]
oi++
}
sorted = sorted[0:oi]
ls.sorted = ls.sorted[0:oi]

// Serialize.
buf := m.pool.Get().(*bytes.Buffer)
defer m.pool.Put(buf)
buf.Reset()
_, _ = buf.WriteRune('|')
delimiter := '#'
for _, kv := range sorted {
for _, kv := range ls.sorted {
_, _ = buf.WriteRune(delimiter)
_, _ = buf.WriteString(string(kv.Key))
_, _ = buf.WriteRune(':')
_, _ = buf.WriteString(kv.Value.Emit())
delimiter = ','
}

return &labels{
meter: m,
sorted: sorted,
encoded: buf.String(),
}
ls.encoded = buf.String()

return ls
}

// labsFor sanitizes the input LabelSet. The input will be rejected
Expand Down

0 comments on commit ee87858

Please sign in to comment.