Skip to content

Commit 74e566e

Browse files
committed
runtime: add readMetrics latency benchmark
This change adds a new benchmark to the runtime tests for measuring the latency of the new metrics implementation, based on the ReadMemStats latency benchmark. readMetrics will have more metrics added to it in the future, and this benchmark will serve as a way to measure the cost of adding additional metrics. Change-Id: Ib05e3ed4afa49a70863fc0c418eab35b72263e24 Reviewed-on: https://go-review.googlesource.com/c/go/+/247042 Run-TryBot: Michael Knyszek <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Michael Knyszek <[email protected]> Reviewed-by: Emmanuel Odeke <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent b08dfba commit 74e566e

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

src/runtime/gc_test.go

+12-5
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ func BenchmarkReadMemStats(b *testing.B) {
518518
hugeSink = nil
519519
}
520520

521-
func BenchmarkReadMemStatsLatency(b *testing.B) {
521+
func applyGCLoad(b *testing.B) func() {
522522
// We’ll apply load to the runtime with maxProcs-1 goroutines
523523
// and use one more to actually benchmark. It doesn't make sense
524524
// to try to run this test with only 1 P (that's what
@@ -563,6 +563,14 @@ func BenchmarkReadMemStatsLatency(b *testing.B) {
563563
runtime.KeepAlive(hold)
564564
}()
565565
}
566+
return func() {
567+
close(done)
568+
wg.Wait()
569+
}
570+
}
571+
572+
func BenchmarkReadMemStatsLatency(b *testing.B) {
573+
stop := applyGCLoad(b)
566574

567575
// Spend this much time measuring latencies.
568576
latencies := make([]time.Duration, 0, 1024)
@@ -579,12 +587,11 @@ func BenchmarkReadMemStatsLatency(b *testing.B) {
579587
runtime.ReadMemStats(&ms)
580588
latencies = append(latencies, time.Now().Sub(start))
581589
}
582-
close(done)
583-
// Make sure to stop the timer before we wait! The goroutines above
584-
// are very heavy-weight and not easy to stop, so we could end up
590+
// Make sure to stop the timer before we wait! The load created above
591+
// is very heavy-weight and not easy to stop, so we could end up
585592
// confusing the benchmarking framework for small b.N.
586593
b.StopTimer()
587-
wg.Wait()
594+
stop()
588595

589596
// Disable the default */op metrics.
590597
// ns/op doesn't mean anything because it's an average, but we

src/runtime/metrics_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ package runtime_test
77
import (
88
"runtime"
99
"runtime/metrics"
10+
"sort"
1011
"strings"
1112
"testing"
13+
"time"
1214
"unsafe"
1315
)
1416

@@ -112,3 +114,39 @@ func TestReadMetricsConsistency(t *testing.T) {
112114
t.Errorf(`"/memory/classes/total:bytes" does not match sum of /memory/classes/**: got %d, want %d`, totalVirtual.got, totalVirtual.want)
113115
}
114116
}
117+
118+
func BenchmarkReadMetricsLatency(b *testing.B) {
119+
stop := applyGCLoad(b)
120+
121+
// Spend this much time measuring latencies.
122+
latencies := make([]time.Duration, 0, 1024)
123+
_, samples := prepareAllMetricsSamples()
124+
125+
// Hit metrics.Read continuously and measure.
126+
b.ResetTimer()
127+
for i := 0; i < b.N; i++ {
128+
start := time.Now()
129+
metrics.Read(samples)
130+
latencies = append(latencies, time.Now().Sub(start))
131+
}
132+
// Make sure to stop the timer before we wait! The load created above
133+
// is very heavy-weight and not easy to stop, so we could end up
134+
// confusing the benchmarking framework for small b.N.
135+
b.StopTimer()
136+
stop()
137+
138+
// Disable the default */op metrics.
139+
// ns/op doesn't mean anything because it's an average, but we
140+
// have a sleep in our b.N loop above which skews this significantly.
141+
b.ReportMetric(0, "ns/op")
142+
b.ReportMetric(0, "B/op")
143+
b.ReportMetric(0, "allocs/op")
144+
145+
// Sort latencies then report percentiles.
146+
sort.Slice(latencies, func(i, j int) bool {
147+
return latencies[i] < latencies[j]
148+
})
149+
b.ReportMetric(float64(latencies[len(latencies)*50/100]), "p50-ns")
150+
b.ReportMetric(float64(latencies[len(latencies)*90/100]), "p90-ns")
151+
b.ReportMetric(float64(latencies[len(latencies)*99/100]), "p99-ns")
152+
}

0 commit comments

Comments
 (0)