Commit 1257d050 authored by Austin Clements's avatar Austin Clements

testing: fix fractional ns/op printing

CL 166717 changed the way ns/op benchmark results were printed and
inadvertently rounded all ns/op results down to an integer, even if
they were small enough to print with digits after the decimal place.
For example, prior to this change, we got output like

    BenchmarkFast-8       380491575	 3.12 ns/op

CL 166717 changed this to

    BenchmarkFast-8       380491575      3.00 ns/op

This had the further side-effect that ns/op values between 0 and 1
would not be printed at all because they would be rounded down to 0.

This CL fixes this by always recomputing the float64 value of ns/op
instead of using the int64 truncation from BenchmarkResult.NsPerOp.

Fixes #30997. Fixes #31005.

Change-Id: I21f73b9d5cc5ad41e7ff535675d07ca00051ecd7
Reviewed-on: https://go-review.googlesource.com/c/go/+/168937Reviewed-by: default avatarJosh Bleecher Snyder <josharian@gmail.com>
parent 94563de8
......@@ -406,9 +406,14 @@ func (r BenchmarkResult) String() string {
buf := new(strings.Builder)
fmt.Fprintf(buf, "%8d", r.N)
if ns := r.NsPerOp(); ns != 0 {
// Get ns/op as a float.
ns, ok := r.Extra["ns/op"]
if !ok {
ns = float64(r.T.Nanoseconds()) / float64(r.N)
}
if ns != 0 {
buf.WriteByte('\t')
prettyPrint(buf, float64(ns), "ns/op")
prettyPrint(buf, ns, "ns/op")
}
if mbs := r.mbPerSec(); mbs != 0 {
......
......@@ -12,6 +12,7 @@ import (
"sync/atomic"
"testing"
"text/template"
"time"
)
var prettyPrintTests = []struct {
......@@ -40,6 +41,32 @@ func TestPrettyPrint(t *testing.T) {
}
}
func TestResultString(t *testing.T) {
// Test fractional ns/op handling
r := testing.BenchmarkResult{
N: 100,
T: 240 * time.Nanosecond,
}
if r.NsPerOp() != 2 {
t.Errorf("NsPerOp: expected 2, actual %v", r.NsPerOp())
}
if want, got := " 100\t 2.40 ns/op", r.String(); want != got {
t.Errorf("String: expected %q, actual %q", want, got)
}
// Test sub-1 ns/op (issue #31005)
r.T = 40 * time.Nanosecond
if want, got := " 100\t 0.400 ns/op", r.String(); want != got {
t.Errorf("String: expected %q, actual %q", want, got)
}
// Test 0 ns/op
r.T = 0
if want, got := " 100", r.String(); want != got {
t.Errorf("String: expected %q, actual %q", want, got)
}
}
func TestRunParallel(t *testing.T) {
testing.Benchmark(func(b *testing.B) {
procs := uint32(0)
......
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