benchstat: split scalers into scaler.go
Change-Id: I20d5f0e2cebef4f577074b45b7849a2698310909
Reviewed-on: https://go-review.googlesource.com/35934
Reviewed-by: Quentin Smith <quentin@golang.org>
diff --git a/cmd/benchstat/main.go b/cmd/benchstat/main.go
index 5a0be1a..734f286 100644
--- a/cmd/benchstat/main.go
+++ b/cmd/benchstat/main.go
@@ -185,7 +185,7 @@
pval, testerr := deltaTest(old, new)
- scaler := newScaler(old.Mean, old.Unit)
+ scaler := NewScaler(old.Mean, old.Unit)
row := newRow(key.Benchmark, old.Format(scaler), new.Format(scaler), "~ ")
if testerr == stats.ErrZeroVariance {
row.add("(zero variance)")
@@ -227,7 +227,7 @@
for _, key.Benchmark = range c.Benchmarks {
row := newRow(key.Benchmark)
- var scaler func(float64) string
+ var scaler Scaler
for _, key.Config = range c.Configs {
m := c.Metrics[key]
if m == nil {
@@ -235,7 +235,7 @@
continue
}
if scaler == nil {
- scaler = newScaler(m.Mean, m.Unit)
+ scaler = NewScaler(m.Mean, m.Unit)
}
row.add(m.Format(scaler))
}
@@ -351,7 +351,7 @@
} else {
geomean := stats.GeoMean(means)
geomeans = append(geomeans, geomean)
- row.add(newScaler(geomean, unit)(geomean) + " ")
+ row.add(NewScaler(geomean, unit)(geomean) + " ")
}
}
if delta {
@@ -360,101 +360,7 @@
return append(table, row)
}
-func timeScaler(ns float64) func(float64) string {
- var format string
- var scale float64
- switch x := ns / 1e9; {
- case x >= 99.5:
- format, scale = "%.0fs", 1
- case x >= 9.95:
- format, scale = "%.1fs", 1
- case x >= 0.995:
- format, scale = "%.2fs", 1
- case x >= 0.0995:
- format, scale = "%.0fms", 1000
- case x >= 0.00995:
- format, scale = "%.1fms", 1000
- case x >= 0.000995:
- format, scale = "%.2fms", 1000
- case x >= 0.0000995:
- format, scale = "%.0fµs", 1000*1000
- case x >= 0.00000995:
- format, scale = "%.1fµs", 1000*1000
- case x >= 0.000000995:
- format, scale = "%.2fµs", 1000*1000
- case x >= 0.0000000995:
- format, scale = "%.0fns", 1000*1000*1000
- case x >= 0.00000000995:
- format, scale = "%.1fns", 1000*1000*1000
- default:
- format, scale = "%.2fns", 1000*1000*1000
- }
- return func(ns float64) string {
- return fmt.Sprintf(format, ns/1e9*scale)
- }
-}
-
-func newScaler(val float64, unit string) func(float64) string {
- if unit == "ns/op" {
- return timeScaler(val)
- }
-
- var format string
- var scale float64
- var suffix string
-
- prescale := 1.0
- if unit == "MB/s" {
- prescale = 1e6
- }
-
- switch x := val * prescale; {
- case x >= 99500000000000:
- format, scale, suffix = "%.0f", 1e12, "T"
- case x >= 9950000000000:
- format, scale, suffix = "%.1f", 1e12, "T"
- case x >= 995000000000:
- format, scale, suffix = "%.2f", 1e12, "T"
- case x >= 99500000000:
- format, scale, suffix = "%.0f", 1e9, "G"
- case x >= 9950000000:
- format, scale, suffix = "%.1f", 1e9, "G"
- case x >= 995000000:
- format, scale, suffix = "%.2f", 1e9, "G"
- case x >= 99500000:
- format, scale, suffix = "%.0f", 1e6, "M"
- case x >= 9950000:
- format, scale, suffix = "%.1f", 1e6, "M"
- case x >= 995000:
- format, scale, suffix = "%.2f", 1e6, "M"
- case x >= 99500:
- format, scale, suffix = "%.0f", 1e3, "k"
- case x >= 9950:
- format, scale, suffix = "%.1f", 1e3, "k"
- case x >= 995:
- format, scale, suffix = "%.2f", 1e3, "k"
- case x >= 99.5:
- format, scale, suffix = "%.0f", 1, ""
- case x >= 9.95:
- format, scale, suffix = "%.1f", 1, ""
- default:
- format, scale, suffix = "%.2f", 1, ""
- }
-
- if unit == "B/op" {
- suffix += "B"
- }
- if unit == "MB/s" {
- suffix += "B/s"
- }
- scale /= prescale
-
- return func(val float64) string {
- return fmt.Sprintf(format+suffix, val/scale)
- }
-}
-
-func (m *Metrics) Format(scaler func(float64) string) string {
+func (m *Metrics) Format(scaler Scaler) string {
diff := 1 - m.Min/m.Mean
if d := m.Max/m.Mean - 1; d > diff {
diff = d
diff --git a/cmd/benchstat/scaler.go b/cmd/benchstat/scaler.go
new file mode 100644
index 0000000..3b24858
--- /dev/null
+++ b/cmd/benchstat/scaler.go
@@ -0,0 +1,109 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+// A Scaler is a function that scales and formats a measurement.
+// All measurements within a given table row are formatted
+// using the same scaler, so that the units are consistent
+// across the row.
+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" {
+ return timeScaler(val)
+ }
+
+ var format string
+ var scale float64
+ var suffix string
+
+ prescale := 1.0
+ if unit == "MB/s" {
+ prescale = 1e6
+ }
+
+ switch x := val * prescale; {
+ case x >= 99500000000000:
+ format, scale, suffix = "%.0f", 1e12, "T"
+ case x >= 9950000000000:
+ format, scale, suffix = "%.1f", 1e12, "T"
+ case x >= 995000000000:
+ format, scale, suffix = "%.2f", 1e12, "T"
+ case x >= 99500000000:
+ format, scale, suffix = "%.0f", 1e9, "G"
+ case x >= 9950000000:
+ format, scale, suffix = "%.1f", 1e9, "G"
+ case x >= 995000000:
+ format, scale, suffix = "%.2f", 1e9, "G"
+ case x >= 99500000:
+ format, scale, suffix = "%.0f", 1e6, "M"
+ case x >= 9950000:
+ format, scale, suffix = "%.1f", 1e6, "M"
+ case x >= 995000:
+ format, scale, suffix = "%.2f", 1e6, "M"
+ case x >= 99500:
+ format, scale, suffix = "%.0f", 1e3, "k"
+ case x >= 9950:
+ format, scale, suffix = "%.1f", 1e3, "k"
+ case x >= 995:
+ format, scale, suffix = "%.2f", 1e3, "k"
+ case x >= 99.5:
+ format, scale, suffix = "%.0f", 1, ""
+ case x >= 9.95:
+ format, scale, suffix = "%.1f", 1, ""
+ default:
+ format, scale, suffix = "%.2f", 1, ""
+ }
+
+ if unit == "B/op" {
+ suffix += "B"
+ }
+ if unit == "MB/s" {
+ suffix += "B/s"
+ }
+ scale /= prescale
+
+ return func(val float64) string {
+ return fmt.Sprintf(format+suffix, val/scale)
+ }
+}
+
+func timeScaler(ns float64) Scaler {
+ var format string
+ var scale float64
+ switch x := ns / 1e9; {
+ case x >= 99.5:
+ format, scale = "%.0fs", 1
+ case x >= 9.95:
+ format, scale = "%.1fs", 1
+ case x >= 0.995:
+ format, scale = "%.2fs", 1
+ case x >= 0.0995:
+ format, scale = "%.0fms", 1000
+ case x >= 0.00995:
+ format, scale = "%.1fms", 1000
+ case x >= 0.000995:
+ format, scale = "%.2fms", 1000
+ case x >= 0.0000995:
+ format, scale = "%.0fµs", 1000*1000
+ case x >= 0.00000995:
+ format, scale = "%.1fµs", 1000*1000
+ case x >= 0.000000995:
+ format, scale = "%.2fµs", 1000*1000
+ case x >= 0.0000000995:
+ format, scale = "%.0fns", 1000*1000*1000
+ case x >= 0.00000000995:
+ format, scale = "%.1fns", 1000*1000*1000
+ default:
+ format, scale = "%.2fns", 1000*1000*1000
+ }
+ return func(ns float64) string {
+ return fmt.Sprintf(format, ns/1e9*scale)
+ }
+}