Skip to content

Commit 01257e6

Browse files
committed
feat(benchstat): implement --update flag to regenerate baselines
1 parent de8befb commit 01257e6

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

cmd/scw-benchstat/main.go

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,22 @@ const (
1919
)
2020

2121
type config struct {
22-
bench string
23-
benchtime string
24-
count int
25-
benchmem bool
26-
failMetrics []string
27-
threshold float64
28-
installTool bool
29-
targetDirs []string
30-
verbose bool
22+
bench string
23+
benchtime string
24+
count int
25+
benchmem bool
26+
failMetrics []string
27+
threshold float64
28+
installTool bool
29+
targetDirs []string
30+
verbose bool
31+
update bool
3132
}
3233

3334
type benchResult struct {
34-
name string
35-
timePerOp float64
36-
bytesPerOp int64
35+
name string
36+
timePerOp float64
37+
bytesPerOp int64
3738
allocsPerOp int64
3839
}
3940

@@ -58,12 +59,17 @@ func main() {
5859
log.Fatal("no benchmark directories found")
5960
}
6061

62+
var hadError bool
6163
for _, dir := range cfg.targetDirs {
6264
if err := runBenchmarksForDir(cfg, dir); err != nil {
63-
log.Printf("failed to run benchmarks for %s: %v", dir, err)
64-
os.Exit(1)
65+
log.Printf("failed to run benchmarks for %s: %v", dir, err)
66+
hadError = true
6567
}
6668
}
69+
70+
if hadError {
71+
os.Exit(1)
72+
}
6773
}
6874

6975
func parseFlags() config {
@@ -76,9 +82,10 @@ func parseFlags() config {
7682
flag.Float64Var(&cfg.threshold, "threshold", 1.5, "performance regression threshold (e.g., 1.5 = 50% slower)")
7783
flag.BoolVar(&cfg.installTool, "install-benchstat", false, "install benchstat tool if not found")
7884
flag.BoolVar(&cfg.verbose, "verbose", false, "verbose output")
85+
flag.BoolVar(&cfg.update, "update", false, "update baseline files instead of comparing")
7986

8087
var failMetricsStr string
81-
flag.StringVar(&failMetricsStr, "fail-metrics", "", "comma-separated list of metrics to check for regressions (time/op,B/op,allocs/op)")
88+
flag.StringVar(&failMetricsStr, "fail-metrics", "", "comma-separated list of metrics to check for regressions (default: time/op)")
8289

8390
var targetDirsStr string
8491
flag.StringVar(&targetDirsStr, "target-dirs", "", "comma-separated list of directories to benchmark")
@@ -87,6 +94,8 @@ func parseFlags() config {
8794

8895
if failMetricsStr != "" {
8996
cfg.failMetrics = strings.Split(failMetricsStr, ",")
97+
} else {
98+
cfg.failMetrics = []string{"time/op"}
9099
}
91100

92101
if targetDirsStr != "" {
@@ -147,6 +156,15 @@ func runBenchmarksForDir(cfg config, dir string) error {
147156
return fmt.Errorf("failed to run benchmarks: %w", err)
148157
}
149158

159+
// Update mode: always overwrite baseline
160+
if cfg.update {
161+
if err := saveBaseline(baselineFile, newResults); err != nil {
162+
return fmt.Errorf("failed to update baseline: %w", err)
163+
}
164+
fmt.Printf("✅ Baseline updated: %s\n", baselineFile)
165+
return nil
166+
}
167+
150168
// Check if baseline exists
151169
if _, err := os.Stat(baselineFile); os.IsNotExist(err) {
152170
fmt.Printf("No baseline found at %s. Creating new baseline.\n", baselineFile)
@@ -163,7 +181,7 @@ func runBenchmarksForDir(cfg config, dir string) error {
163181

164182
func runBenchmarks(cfg config, dir string) (string, error) {
165183
args := []string{"test", "-bench=" + cfg.bench, "-benchtime=" + cfg.benchtime, "-count=" + strconv.Itoa(cfg.count)}
166-
184+
167185
if cfg.benchmem {
168186
args = append(args, "-benchmem")
169187
}

0 commit comments

Comments
 (0)