Skip to content

Commit 8cd8fbd

Browse files
committed
sql/tests: speed-up sysbench micro-benchmarks
The sysbench micro-benchmarks have been sped up by avoiding repeatedly setting up a new cluster while Go's benchmarking harness ramps up `b.N`. Prior to this commit the benchmark command below took ~112 seconds and now takes ~36 seconds on my Mac M1 Pro. ./dev bench pkg/sql/tests \ -f 'BenchmarkSysbench/SQL/1node_local/oltp_point_select' \ --count 3 See the inline comments for more details. Release note: None
1 parent ccfeb69 commit 8cd8fbd

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

pkg/sql/tests/sysbench_test.go

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -863,41 +863,50 @@ func benchmarkSysbenchImpl(b *testing.B, parallel bool) {
863863
for _, driver := range drivers {
864864
b.Run(driver.name, func(b *testing.B) {
865865
for _, workload := range workloads {
866+
var sys sysbenchDriver
867+
var cleanup func()
866868
b.Run(workload.name, func(b *testing.B) {
867869
defer func() {
868870
if r := recover(); r != nil {
869871
b.Fatalf("%+v", r)
870872
}
871873
}()
872874

873-
// NB: this can be removed once this test is refactored to use `b.Loop`
874-
// available starting in go1.24[1]
875+
// NB: this can be removed once this test is refactored to
876+
// use `b.Loop` available starting in go1.24[1]
875877
//
876878
// [1]: https://tip.golang.org/doc/go1.24#new-benchmark-function
877-
var benchtime string
878-
require.NoError(b, sniffarg.DoEnv("test.benchtime", &benchtime))
879-
if strings.HasSuffix(benchtime, "x") && b.N == 1 && benchtime != "1x" {
880-
// The Go benchmark harness invokes tests first with b.N == 1 which
881-
// helps it adjust the number of iterations to run to the benchtime.
882-
// But if we specify the number of iterations, there's no point in
883-
// it doing that, so we no-op on the first run.
884-
// This speeds up benchmarking (by several seconds per subtest!)
885-
// since it avoids setting up an extra test cluster.
886-
b.Log("skipping benchmark on initial run; benchtime specifies an iteration count")
887-
return
879+
if b.N == 1 && sys != nil {
880+
// The Go benchmark harness will run a benchmark with
881+
// b.N=1 first, and ramp up b.N until the benchmark hits
882+
// a time threshold. This means that the setup code will
883+
// run multiple times for a single benchmark result. To
884+
// avoid repeatedly incurring the overhead of
885+
// re-prepping the test cluster, we only run the setup
886+
// code when on the first execution of each iteration of
887+
// the benchmark, when b.N=1. If the benchmark is run
888+
// with --count greater than 1, then b.N will be reset
889+
// to 1 for each iteration, and a new cluster will be
890+
// created, ensuring benchmark results across
891+
// interations remain independent.
892+
cleanup()
893+
sys = nil
894+
}
895+
if sys == nil {
896+
sys, cleanup = driver.constructorFn(context.Background(), b)
897+
sys.prep(rand.New(rand.NewSource(0)))
888898
}
889-
sys, cleanup := driver.constructorFn(context.Background(), b)
890-
defer cleanup()
891899
runSysbenchOuter(b, sys, workload.opFn, parallel)
892900
})
901+
if cleanup != nil {
902+
cleanup()
903+
}
893904
}
894905
})
895906
}
896907
}
897908

898909
func runSysbenchOuter(b *testing.B, sys sysbenchDriver, opFn sysbenchWorkload, parallel bool) {
899-
sys.prep(rand.New(rand.NewSource(0)))
900-
901910
defer startAllocsProfile(b).Stop(b)
902911
defer b.StopTimer()
903912

0 commit comments

Comments
 (0)