]> Cypherpunks repositories - gostls13.git/commitdiff
testing: fix fractional ns/op printing
authorAustin Clements <austin@google.com>
Fri, 22 Mar 2019 18:18:22 +0000 (14:18 -0400)
committerAustin Clements <austin@google.com>
Fri, 22 Mar 2019 21:19:22 +0000 (21:19 +0000)
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/+/168937
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/testing/benchmark.go
src/testing/benchmark_test.go

index 407e371c667d2595709d0563d3d0984f035b3515..6dcfcb02c74843c04a6262b77015f062dff40ba9 100644 (file)
@@ -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 {
index 7d28fb632a426dcc59100e6fd2c1448706c7d019..a872d6798b592500748ed0423efa2d393a1142c3 100644 (file)
@@ -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)