diff --git a/bridge/opencensus/internal/ocmetric/metric.go b/bridge/opencensus/internal/ocmetric/metric.go index 4e0c925be..4d053e801 100644 --- a/bridge/opencensus/internal/ocmetric/metric.go +++ b/bridge/opencensus/internal/ocmetric/metric.go @@ -4,11 +4,12 @@ package internal // import "go.opentelemetry.io/otel/bridge/opencensus/internal/ocmetric" import ( + "cmp" "errors" "fmt" "math" "reflect" - "sort" + "slices" "strconv" ocmetricdata "go.opencensus.io/metric/metricdata" @@ -200,8 +201,9 @@ func convertExemplar(ocExemplar *ocmetricdata.Exemplar) (metricdata.Exemplar[flo exemplar.FilteredAttributes = append(exemplar.FilteredAttributes, convertKV(k, v)) } } - sortable := attribute.Sortable(exemplar.FilteredAttributes) - sort.Sort(&sortable) + slices.SortFunc(exemplar.FilteredAttributes, func(a, b attribute.KeyValue) int { + return cmp.Compare(a.Key, b.Key) + }) return exemplar, err } @@ -377,18 +379,12 @@ func convertQuantiles(snapshot ocmetricdata.Snapshot) []metricdata.QuantileValue Value: value, }) } - sort.Sort(byQuantile(quantileValues)) + slices.SortFunc(quantileValues, func(a, b metricdata.QuantileValue) int { + return cmp.Compare(a.Quantile, b.Quantile) + }) return quantileValues } -// byQuantile implements sort.Interface for []metricdata.QuantileValue -// based on the Quantile field. -type byQuantile []metricdata.QuantileValue - -func (a byQuantile) Len() int { return len(a) } -func (a byQuantile) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byQuantile) Less(i, j int) bool { return a[i].Quantile < a[j].Quantile } - // convertAttrs converts from OpenCensus attribute keys and values to an // OpenTelemetry attribute Set. func convertAttrs(keys []ocmetricdata.LabelKey, values []ocmetricdata.LabelValue) (attribute.Set, error) { diff --git a/bridge/opencensus/internal/ocmetric/metric_test.go b/bridge/opencensus/internal/ocmetric/metric_test.go index 8e79c169a..afdcfaa9e 100644 --- a/bridge/opencensus/internal/ocmetric/metric_test.go +++ b/bridge/opencensus/internal/ocmetric/metric_test.go @@ -7,7 +7,9 @@ import ( "errors" "fmt" "math" + "math/rand" "reflect" + "strconv" "testing" "time" @@ -1168,3 +1170,57 @@ func TestConvertKV(t *testing.T) { }) } } + +func BenchmarkConvertExemplar(b *testing.B) { + const attchmentsN = 10 + data := make([]*ocmetricdata.Exemplar, b.N) + for i := range data { + a := make(ocmetricdata.Attachments, attchmentsN) + for j := 0; j < attchmentsN; j++ { + a[strconv.Itoa(j)] = rand.Int63() + } + data[i] = &ocmetricdata.Exemplar{ + Value: rand.NormFloat64(), + Timestamp: time.Now(), + Attachments: a, + } + } + + var out metricdata.Exemplar[float64] + + b.ReportAllocs() + b.ResetTimer() + for n := 0; n < b.N; n++ { + out, _ = convertExemplar(data[n]) + } + + _ = out +} + +func BenchmarkConvertQuantiles(b *testing.B) { + const percentileN = 20 + data := make([]ocmetricdata.Snapshot, b.N) + for i := range data { + p := make(map[float64]float64, percentileN) + for j := 0; j < percentileN; j++ { + v := rand.Float64() + for v == 0 { + // Convert from [0, 1) interval to (0, 1). + v = rand.Float64() + } + v *= 100 // Convert from (0, 1) interval to (0, 100). + p[v] = rand.ExpFloat64() + } + data[i] = ocmetricdata.Snapshot{Percentiles: p} + } + + var out []metricdata.QuantileValue + + b.ReportAllocs() + b.ResetTimer() + for n := 0; n < b.N; n++ { + out = convertQuantiles(data[n]) + } + + _ = out +}