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: Quentin Smith <quentin@golang.org>
diff --git a/benchstat/scaler.go b/benchstat/scaler.go
index c775caa..7b652f1 100644
--- a/benchstat/scaler.go
+++ b/benchstat/scaler.go
@@ -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 @@
// 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 @@
var suffix string
prescale := 1.0
- if unit == "MB/s" {
+ if hasBaseUnit(unit, "MB/s") {
prescale = 1e6
}
@@ -61,10 +64,10 @@
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 @@
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)
+}
diff --git a/benchstat/table.go b/benchstat/table.go
index 9693389..ef938d1 100644
--- a/benchstat/table.go
+++ b/benchstat/table.go
@@ -6,6 +6,7 @@
import (
"fmt"
+ "strings"
"golang.org/x/perf/internal/stats"
)
@@ -126,18 +127,25 @@
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,
diff --git a/cmd/benchstat/main_test.go b/cmd/benchstat/main_test.go
index 26f5433..4653ae0 100644
--- a/cmd/benchstat/main_test.go
+++ b/cmd/benchstat/main_test.go
@@ -38,6 +38,7 @@
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) {
diff --git a/cmd/benchstat/testdata/units-new.txt b/cmd/benchstat/testdata/units-new.txt
new file mode 100644
index 0000000..397088d
--- /dev/null
+++ b/cmd/benchstat/testdata/units-new.txt
@@ -0,0 +1,8 @@
+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
diff --git a/cmd/benchstat/testdata/units-old.txt b/cmd/benchstat/testdata/units-old.txt
new file mode 100644
index 0000000..6e87b07
--- /dev/null
+++ b/cmd/benchstat/testdata/units-old.txt
@@ -0,0 +1,8 @@
+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
diff --git a/cmd/benchstat/testdata/units.golden b/cmd/benchstat/testdata/units.golden
new file mode 100644
index 0000000..3a5ca67
--- /dev/null
+++ b/cmd/benchstat/testdata/units.golden
@@ -0,0 +1,11 @@
+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)