Skip to content

Commit

Permalink
refactor: parametrize bench runner
Browse files Browse the repository at this point in the history
  • Loading branch information
katcipis committed Jan 1, 2024
1 parent 292ac03 commit 567cdce
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 49 deletions.
101 changes: 53 additions & 48 deletions benchcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,57 @@ import (
// CheckerFmt represents the expected string format of a checker.
const CheckerFmt = "<metric>=(+|-)<number>%"

// Module represents a Go module.
type Module struct {
path string
}
type (
// Module represents a Go module.
Module struct {
path string
}

// StatResult is the full result showing performance
// differences between two benchmark runs (set of benchmark functions)
// for a specific metric, like time/op or speed.
type StatResult struct {
// Metric is the name of metric
Metric string
// BenchDiffs has the performance diff of all function for a given metric.
BenchDiffs []BenchDiff
}
// StatResult is the full result showing performance
// differences between two benchmark runs (set of benchmark functions)
// for a specific metric, like time/op or speed.
StatResult struct {
// Metric is the name of metric
Metric string
// BenchDiffs has the performance diff of all function for a given metric.
BenchDiffs []BenchDiff
}

// BenchResults represents a single Go benchmark run. Each
// string is the result of a single Benchmark like this:
// - "BenchmarkName 50 31735022 ns/op 61.15 MB/s"
type BenchResults []string

// BenchDiff is the result showing performance differences
// for a single benchmark function.
type BenchDiff struct {
// Name of the benchmark function
Name string
// Old is the performance summary of the old benchmark.
Old string
// New is the performance summary of the new benchmark.
New string
// Delta between the old and new performance summaries.
Delta float64
}
// BenchResults represents a single Go benchmark run. Each
// string is the result of a single Benchmark like this:
// - "BenchmarkName 50 31735022 ns/op 61.15 MB/s"
BenchResults []string

// BenchRunner runs benchmarks
BenchRunner func(Module) (BenchResults, error)

// BenchDiff is the result showing performance differences
// for a single benchmark function.
BenchDiff struct {
// Name of the benchmark function
Name string
// Old is the performance summary of the old benchmark.
Old string
// New is the performance summary of the new benchmark.
New string
// Delta between the old and new performance summaries.
Delta float64
}

// Checker performs checks on StatResult.
type Checker struct {
metric string
threshold float64
repr string
}
// Checker performs checks on StatResult.
Checker struct {
metric string
threshold float64
repr string
}

// CmdError represents an error running a specific command.
type CmdError struct {
Cmd *exec.Cmd
Err error
Output string
}
// CmdError represents an error running a specific command.
CmdError struct {
Cmd *exec.Cmd
Err error
Output string
}
)

// Error returns the string representation of the error.
func (c *CmdError) Error() string {
Expand Down Expand Up @@ -205,20 +210,20 @@ func Stat(oldres BenchResults, newres BenchResults) ([]StatResult, error) {
// StatModule will:
//
// - Download the specific versions of the given module.
// - Run benchmarks on each of them.
// - Run benchmarks on each of them using the provided [BenchRunner].
// - Compare old vs new version benchmarks and return a stat results.
//
// This function relies on running the "go" command to run benchmarks.
//
// Any errors running "go" can be inspected in detail by
// checking if the returned error is a CmdError.
func StatModule(name string, oldversion, newversion string) ([]StatResult, error) {
oldresults, err := benchModule(name, oldversion)
func StatModule(runBench BenchRunner, name string, oldversion, newversion string) ([]StatResult, error) {
oldresults, err := benchModule(runBench, name, oldversion)
if err != nil {
return nil, fmt.Errorf("running bench for old module: %v", err)
}

newresults, err := benchModule(name, newversion)
newresults, err := benchModule(runBench, name, newversion)
if err != nil {
return nil, fmt.Errorf("running bench for new module: %v", err)
}
Expand Down Expand Up @@ -282,7 +287,7 @@ func resultsReader(res BenchResults) io.Reader {
return strings.NewReader(strings.Join(res, "\n"))
}

func benchModule(name string, version string) (BenchResults, error) {
func benchModule(runBench BenchRunner, name string, version string) (BenchResults, error) {
mod, err := GetModule(name, version)
if err != nil {
return nil, err
Expand All @@ -294,7 +299,7 @@ func benchModule(name string, version string) (BenchResults, error) {
results := BenchResults{}

for i := 0; i < benchruns; i++ {
res, err := RunBench(mod)
res, err := runBench(mod)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/benchcheck/benchcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func main() {
log.Fatal("-new is obligatory")
}

results, err := benchcheck.StatModule(*mod, *oldRev, *newRev)
results, err := benchcheck.StatModule(benchcheck.RunBench, *mod, *oldRev, *newRev)
if err != nil {
var cmderr *benchcheck.CmdError
if errors.As(err, &cmderr) {
Expand Down

0 comments on commit 567cdce

Please sign in to comment.