Skip to content

Commit

Permalink
improvement: Use go1.21's slices package to avoid allocation in sorti…
Browse files Browse the repository at this point in the history
…ng (#323)
  • Loading branch information
bmoylan authored Sep 8, 2023
1 parent 446e5da commit f9e2fb6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
5 changes: 2 additions & 3 deletions metrics/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package metrics

import (
"context"
"sort"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -269,7 +268,7 @@ func (r *rootRegistry) Each(f MetricVisitor) {
sortedMetricIDs = append(sortedMetricIDs, name)
allMetrics[name] = metric
})
sort.Strings(sortedMetricIDs)
sortStrings(sortedMetricIDs)

for _, id := range sortedMetricIDs {
r.idToMetricMutex.RLock()
Expand Down Expand Up @@ -401,6 +400,6 @@ func toMetricTagsID(name string, tags Tags) metricTagsID {
// newSortedTags copies the tag slice before sorting so that in-place mutation does not affect the input slice.
func newSortedTags(tags Tags) Tags {
tagsCopy := append(tags[:0:0], tags...)
sort.Sort(tagsCopy)
sortTags(tagsCopy)
return tagsCopy
}
23 changes: 23 additions & 0 deletions metrics/sort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2023 Palantir Technologies. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !go1.21

package metrics

import (
"sort"
)

// sortStrings is the default sort.Strings function.
// Unfortunately this forces the slice to escape to the heap.
// See https://github.com/golang/go/issues/17332
// Go 1.21's slices package does not have this issue.
var sortStrings = sort.Strings

// sortTags is the default sort.Sort function.
// Unfortunately this forces the slice to escape to the heap.
// See https://github.com/golang/go/issues/17332
// Go 1.21's slices package does not have this issue.
var sortTags = sort.Sort
30 changes: 30 additions & 0 deletions metrics/sort_go121.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2023 Palantir Technologies. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build go1.21

package metrics

import (
"slices"
)

// sortStrings is the default slices.Sort function which does not force allocation like sort.Strings.
var sortStrings = slices.Sort[[]string]

// sortTags uses slices.SortFunc which does not force allocation like sort.Sort.
func sortTags(tags Tags) {
slices.SortFunc(tags, compareTags)
}

func compareTags(a, b Tag) int {
switch {
case a.keyValue > b.keyValue:
return 1
case a.keyValue == b.keyValue:
return 0
default:
return -1
}
}

0 comments on commit f9e2fb6

Please sign in to comment.