Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add (and default to on) --preview #6

Merged
merged 4 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2025 The Cockroach Authors.
//
// Use of this software is governed by the CockroachDB Software License
// included in the /LICENSE file.

package main

import (
"testing"
"time"
)

// BenchmarkDummy does not measure anything meaningful, but is helpful for
// quickly iterating on UI changes to `benchdiff`, for example with the
// following invocation: go run . --old HEAD . -r '.' -d 50ms -c 25
func BenchmarkDummy(b *testing.B) {
b.ReportAllocs()
var cnt int
for i := 0; i < b.N; i++ {
sl := make([]int, 1024)
sl[0], sl[1] = 1, int(time.Now().UnixNano())
for j := 2; j < len(sl); j++ {
sl[j] = sl[j-1]*sl[j-2] + 1
}
cnt += sl[len(sl)-1]
}
}
35 changes: 25 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Options:
-p, --previous-run <time> time of previous run; skip running benches and just (re)process previous run
--post-checkout an optional command to run after checking out each branch to
configure the git repo so that 'go build' succeeds
--preview show benchdiff text output while benchmarks are being run (default true)
-b --bazel build the test binaries with bazel
-s --sort <order> sort output by 'delta' (largest first) or 'name'
--csv output the results in a csv format
Expand Down Expand Up @@ -137,6 +138,7 @@ func run(ctx context.Context) error {
var cpuProfile, memProfile, mutexProfile bool
var threshold float64
var useBazel bool
var preview bool

pflag.Usage = func() { fmt.Fprintln(os.Stderr, usage) }
pflag.BoolVarP(&help, "help", "h", false, "")
Expand All @@ -156,6 +158,7 @@ func run(ctx context.Context) error {
pflag.BoolVarP(&mutexProfile, "mutexprofile", "", false, "")
pflag.Float64VarP(&threshold, "threshold", "t", -1, "")
pflag.StringVarP(&previousRun, "previous-run", "p", "", "")
pflag.BoolVarP(&preview, "preview", "", true, "")
pflag.Parse()
prArgs := pflag.Args()

Expand Down Expand Up @@ -226,7 +229,7 @@ func run(ctx context.Context) error {
tests := oldSuite.intersectTests(&newSuite)
err = runCmpBenches(
ctx, &oldSuite, &newSuite, tests.sorted(), runPattern,
benchTime, cpuProfile, memProfile, mutexProfile, itersPerTest,
benchTime, cpuProfile, memProfile, mutexProfile, itersPerTest, preview,
)
if err != nil {
return err
Expand All @@ -253,7 +256,7 @@ func run(ctx context.Context) error {
fmt.Fprintf(os.Stderr, "Found previous run; old=%s, new=%s\n", oldSuite.outFile.Name(), newSuite.outFile.Name())
}
// Process the benchmark output.
res, err := processBenchOutput(ctx, &oldSuite, &newSuite, order == "name", out, pkgFilter, srv)
res, err := processBenchOutput(ctx, os.Stdout, &oldSuite, &newSuite, order == "name", out, pkgFilter, srv)
if err != nil {
return err
}
Expand Down Expand Up @@ -336,17 +339,28 @@ func runCmpBenches(
runPattern, benchTime string,
cpuProfile, memProfile, mutexProfile bool,
itersPerTest int,
preview bool,
) error {
var spinner ui.Spinner
spinner.Start(os.Stderr, "running benchmarks:")
spinner.Start(os.Stderr, "running benchmarks:\n")
defer spinner.Stop()
for i, t := range tests {
pkg := testBinToPkg(t)
for j := 0; j < itersPerTest; j++ {
pkgFrac := ui.Fraction(i+1, len(tests))
iterFrac := ui.Fraction(j+1, itersPerTest)
progress := fmt.Sprintf(" pkg=%s iter=%s %s", pkgFrac, iterFrac, pkg)
spinner.Update(progress)
var buf bytes.Buffer
if preview && j > 0 {
_, err := processBenchOutput(ctx, &buf, bs1, bs2, true, text, tests, nil)
tbg marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
_, _ = fmt.Fprintln(&buf)
tbg marked this conversation as resolved.
Show resolved Hide resolved
}
_, _ = fmt.Fprintf(&buf, "pkg=%s iter=%s %s",
pkgFrac, iterFrac,
pkg)
spinner.Update(buf.String())

// Interleave test suite runs instead of using -count=itersPerTest. The
// idea is that this reduces the chance that we pick up external noise
Expand Down Expand Up @@ -409,6 +423,7 @@ func runSingleBench(

func processBenchOutput(
ctx context.Context,
w io.Writer,
oldSuite, newSuite *benchSuite,
byName bool, // instead of by delta reversed
out outputFmt,
Expand Down Expand Up @@ -438,19 +453,19 @@ func processBenchOutput(
// Output the results.
switch out {
case text:
benchstat.FormatText(os.Stdout, tables)
benchstat.FormatText(w, tables)
case csv:
// If norange is true, suppress the range information for each data item.
// If norange is false, insert a "±" in the appropriate columns of the header row.
norange := false
benchstat.FormatCSV(os.Stdout, tables, norange)
benchstat.FormatCSV(w, tables, norange)
case html:
var buf bytes.Buffer
benchstat.FormatHTML(&buf, tables)
io.Copy(os.Stdout, &buf)
io.Copy(w, &buf)
case sheets:
// When outputting a Google sheet, also output as text first.
benchstat.FormatText(os.Stdout, tables)
benchstat.FormatText(w, tables)

sheetName := fmt.Sprintf("benchdiff: %s (%s -> %s)",
strings.Join(pkgFilter, " "), oldSuite.ref, newSuite.ref)
Expand Down Expand Up @@ -578,7 +593,7 @@ func (bs *benchSuite) build(pkgFilter []string, postChck string, t time.Time) (e
}

var spinner ui.Spinner
spinner.Start(os.Stderr, fmt.Sprintf("building benchmark binaries for %s: %.50s [bazel=%t]", bs.ref,
spinner.Start(os.Stderr, fmt.Sprintf("building benchmark binaries for %s: %.50s [bazel=%t] ", bs.ref,
bs.subject, bs.useBazel))
defer spinner.Stop()
for i, pkg := range pkgs {
Expand Down
2 changes: 1 addition & 1 deletion ui/spinner.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (s *Spinner) Start(out io.Writer, prefix string) {
}
fmt.Fprint(&s.w, prefix)
if progress != "" {
fmt.Fprintf(&s.w, " %s", progress)
fmt.Fprint(&s.w, progress)
}
fmt.Fprintf(&s.w, " %s\n", spinnerChars[spinnerIdx%len(spinnerChars)])
if err := s.w.Flush(out); err != nil {
Expand Down