Commit 0da03b58 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

benchstat: handle user-ns/op units

compilebench emits both ns/op and user-ns/op measurements.
This CL improves benchstat's handling of such measurements.
Migrated from https://github.com/rsc/benchstat/pull/5.

Sample output, before:

name       old user-ns/op  new user-ns/op  delta
Template        279M ± 7%       273M ± 4%     ~     (p=0.329 n=6+5)
Unicode         148M ±11%       131M ± 7%  -11.49%  (p=0.030 n=6+5)
GoTypes         830M ± 2%       835M ± 3%     ~     (p=0.792 n=6+5)
SSA            9.60G ± 3%      9.64G ± 2%     ~     (p=0.792 n=6+5)
Flate           158M ± 3%       155M ± 1%     ~     (p=0.329 n=6+5)
GoParser        204M ± 6%       202M ± 8%     ~     (p=0.792 n=6+5)
Reflect         511M ± 9%       531M ± 6%     ~     (p=0.177 n=6+5)
Tar             151M ± 3%       151M ± 5%     ~     (p=0.931 n=6+5)
XML             271M ± 3%       268M ± 3%     ~     (p=0.429 n=6+5)

Sample output, after:

name       old user-time/op  new user-time/op  delta
Template         279ms ± 7%        273ms ± 4%     ~     (p=0.329 n=6+5)
Unicode          148ms ±11%        131ms ± 7%  -11.49%  (p=0.030 n=6+5)
GoTypes          830ms ± 2%        835ms ± 3%     ~     (p=0.792 n=6+5)
SSA              9.60s ± 3%        9.64s ± 2%     ~     (p=0.792 n=6+5)
Flate            158ms ± 3%        155ms ± 1%     ~     (p=0.329 n=6+5)
GoParser         204ms ± 6%        202ms ± 8%     ~     (p=0.792 n=6+5)
Reflect          511ms ± 9%        531ms ± 6%     ~     (p=0.177 n=6+5)
Tar              151ms ± 3%        151ms ± 5%     ~     (p=0.931 n=6+5)
XML              271ms ± 3%        268ms ± 3%     ~     (p=0.429 n=6+5)

Change-Id: I716b4e89a28adc72e9135b8c580434f748a9c0a9
Reviewed-on: https://go-review.googlesource.com/39794
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarQuentin Smith <quentin@golang.org>
parent 844f0140
......@@ -4,7 +4,10 @@
package benchstat
import "fmt"
import (
"fmt"
"strings"
)
// A Scaler is a function that scales and formats a measurement.
// All measurements within a given table row are formatted
......@@ -15,7 +18,7 @@ type Scaler func(float64) string
// NewScaler returns a Scaler appropriate for formatting
// the measurement val, which has the given unit.
func NewScaler(val float64, unit string) Scaler {
if unit == "ns/op" {
if hasBaseUnit(unit, "ns/op") || hasBaseUnit(unit, "ns/GC") {
return timeScaler(val)
}
......@@ -24,7 +27,7 @@ func NewScaler(val float64, unit string) Scaler {
var suffix string
prescale := 1.0
if unit == "MB/s" {
if hasBaseUnit(unit, "MB/s") {
prescale = 1e6
}
......@@ -61,10 +64,10 @@ func NewScaler(val float64, unit string) Scaler {
format, scale, suffix = "%.2f", 1, ""
}
if unit == "B/op" {
if hasBaseUnit(unit, "B/op") || hasBaseUnit(unit, "bytes/op") || hasBaseUnit(unit, "bytes") {
suffix += "B"
}
if unit == "MB/s" {
if hasBaseUnit(unit, "MB/s") {
suffix += "B/s"
}
scale /= prescale
......@@ -107,3 +110,9 @@ func timeScaler(ns float64) Scaler {
return fmt.Sprintf(format, ns/1e9*scale)
}
}
// hasBaseUnit reports whether s has unit unit.
// For now, it reports whether s == unit or s ends in -unit.
func hasBaseUnit(s, unit string) bool {
return s == unit || strings.HasSuffix(s, "-"+unit)
}
......@@ -6,6 +6,7 @@ package benchstat
import (
"fmt"
"strings"
"golang.org/x/perf/internal/stats"
)
......@@ -126,18 +127,25 @@ func (c *Collection) Tables() []*Table {
return tables
}
var metricSuffix = map[string]string{
"ns/op": "time/op",
"ns/GC": "time/GC",
"B/op": "alloc/op",
"MB/s": "speed",
}
// metricOf returns the name of the metric with the given unit.
func metricOf(unit string) string {
switch unit {
case "ns/op":
return "time/op"
case "B/op":
return "alloc/op"
case "MB/s":
return "speed"
default:
return unit
if s := metricSuffix[unit]; s != "" {
return s
}
for s, suff := range metricSuffix {
if dashs := "-" + s; strings.HasSuffix(unit, dashs) {
prefix := strings.TrimSuffix(unit, dashs)
return prefix + "-" + suff
}
}
return unit
}
// addGeomean adds a "geomean" row to the table,
......
......@@ -38,6 +38,7 @@ func TestGolden(t *testing.T) {
check(t, "oldnewttest", "-delta-test=ttest", "old.txt", "new.txt")
check(t, "packagesold", "packagesold.txt")
check(t, "packages", "packagesold.txt", "packagesnew.txt")
check(t, "units", "units-old.txt", "units-new.txt")
}
func check(t *testing.T, name string, files ...string) {
......
pkg: synthetic
note: test benchstat printing of units
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14100000000000 user-ns/op 5 ns/GC 12 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14700000000000 user-ns/op 5 ns/GC 16 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14800000000000 user-ns/op 5 ns/GC 12 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14300000000000 user-ns/op 5 ns/GC 16 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14000000000000 user-ns/op 5 ns/GC 12 quick-bytes
pkg: synthetic
note: test benchstat printing of units
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14400000000000 user-ns/op 5 ns/GC 12 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14500000000000 user-ns/op 5 ns/GC 16 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14600000000000 user-ns/op 5 ns/GC 12 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14200000000000 user-ns/op 5 ns/GC 16 quick-bytes
BenchmarkTwoHourMarathon 1 7200000000000 ns/op 14300000000000 user-ns/op 5 ns/GC 12 quick-bytes
name old time/op new time/op delta
TwoHourMarathon 7200s ± 0% 7200s ± 0% ~ (all equal)
name old user-time/op new user-time/op delta
TwoHourMarathon 14400s ± 1% 14380s ± 3% ~ (p=0.881 n=5+5)
name old time/GC new time/GC delta
TwoHourMarathon 5.00ns ± 0% 5.00ns ± 0% ~ (all equal)
name old quick-bytes new quick-bytes delta
TwoHourMarathon 13.6B ±18% 13.6B ±18% ~ (p=1.000 n=5+5)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment