metrics: optimize expdecaysample, avoid iteration of values

This commit is contained in:
Martin Holst Swende 2023-09-01 11:13:41 +02:00
parent 4ae74271ca
commit 9723df673d
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -83,13 +83,26 @@ func (s *ExpDecaySample) Clear() {
// Snapshot returns a read-only copy of the sample. // Snapshot returns a read-only copy of the sample.
func (s *ExpDecaySample) Snapshot() SampleSnapshot { func (s *ExpDecaySample) Snapshot() SampleSnapshot {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock()
vals := s.values.Values() vals := s.values.Values()
values := make([]int64, len(vals)) values := make([]int64, len(vals))
for i, v := range vals { var (
values[i] = v.v max int64 = math.MinInt64
min int64 = math.MaxInt64
sum int64
)
for i, item := range vals {
v := item.v
values[i] = v
sum += v
if v > max {
max = v
} }
s.mutex.Unlock() if v < min {
return newSampleSnapshot(s.count, values) min = v
}
}
return newSampleSnapshotPrecalculated(s.count, values, min, max, sum)
} }
// Update samples a new value. // Update samples a new value.
@ -221,16 +234,29 @@ type sampleSnapshot struct {
sum int64 sum int64
} }
// newSampleSnapshot creates a read-only sampleSnapShot, and calculates some // newSampleSnapshotPrecalculated creates a read-only sampleSnapShot, using
// numbers. // precalculated sums to avoid iterating the values
func newSampleSnapshot(count int64, values []int64) *sampleSnapshot { func newSampleSnapshotPrecalculated(count int64, values []int64,
s := &sampleSnapshot{ min, max, sum int64) *sampleSnapshot {
if len(values) == 0 {
return &sampleSnapshot{
count: count, count: count,
values: values, values: values,
} }
if len(values) == 0 {
return s
} }
return &sampleSnapshot{
count: count,
values: values,
max: max,
min: min,
mean: float64(sum) / float64(len(values)),
sum: sum,
}
}
// newSampleSnapshot creates a read-only sampleSnapShot, and calculates some
// numbers.
func newSampleSnapshot(count int64, values []int64) *sampleSnapshot {
var ( var (
max int64 = math.MinInt64 max int64 = math.MinInt64
min int64 = math.MaxInt64 min int64 = math.MaxInt64
@ -245,11 +271,7 @@ func newSampleSnapshot(count int64, values []int64) *sampleSnapshot {
min = v min = v
} }
} }
s.min = min return newSampleSnapshotPrecalculated(count, values, min, max, sum)
s.max = max
s.mean = float64(sum) / float64(len(values))
s.sum = sum
return s
} }
// Count returns the count of inputs at the time the snapshot was taken. // Count returns the count of inputs at the time the snapshot was taken.