golang.org/x/tools@v0.21.0/cmd/benchcmp/compare_test.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"math"
     9  	"reflect"
    10  	"sort"
    11  	"testing"
    12  
    13  	"golang.org/x/tools/benchmark/parse"
    14  )
    15  
    16  func TestDelta(t *testing.T) {
    17  	cases := []struct {
    18  		before  float64
    19  		after   float64
    20  		mag     float64
    21  		f       float64
    22  		changed bool
    23  		pct     string
    24  		mult    string
    25  	}{
    26  		{before: 1, after: 1, mag: 1, f: 1, changed: false, pct: "+0.00%", mult: "1.00x"},
    27  		{before: 1, after: 2, mag: 0.5, f: 2, changed: true, pct: "+100.00%", mult: "2.00x"},
    28  		{before: 2, after: 1, mag: 0.5, f: 0.5, changed: true, pct: "-50.00%", mult: "0.50x"},
    29  		{before: 0, after: 0, mag: 1, f: 1, changed: false, pct: "+0.00%", mult: "1.00x"},
    30  		{before: 1, after: 0, mag: math.Inf(1), f: 0, changed: true, pct: "-100.00%", mult: "0.00x"},
    31  		{before: 0, after: 1, mag: math.Inf(1), f: math.Inf(1), changed: true, pct: "+Inf%", mult: "+Infx"},
    32  	}
    33  	for _, tt := range cases {
    34  		d := Delta{tt.before, tt.after}
    35  		if want, have := tt.mag, d.mag(); want != have {
    36  			t.Errorf("%s.mag(): want %f have %f", d, want, have)
    37  		}
    38  		if want, have := tt.f, d.Float64(); want != have {
    39  			t.Errorf("%s.Float64(): want %f have %f", d, want, have)
    40  		}
    41  		if want, have := tt.changed, d.Changed(); want != have {
    42  			t.Errorf("%s.Changed(): want %t have %t", d, want, have)
    43  		}
    44  		if want, have := tt.pct, d.Percent(); want != have {
    45  			t.Errorf("%s.Percent(): want %q have %q", d, want, have)
    46  		}
    47  		if want, have := tt.mult, d.Multiple(); want != have {
    48  			t.Errorf("%s.Multiple(): want %q have %q", d, want, have)
    49  		}
    50  	}
    51  }
    52  
    53  func TestCorrelate(t *testing.T) {
    54  	// Benches that are going to be successfully correlated get N thus:
    55  	//   0x<counter><num benches><b = before | a = after>
    56  	// Read this: "<counter> of <num benches>, from <before|after>".
    57  	before := parse.Set{
    58  		"BenchmarkOneEach":   []*parse.Benchmark{{Name: "BenchmarkOneEach", N: 0x11b}},
    59  		"BenchmarkOneToNone": []*parse.Benchmark{{Name: "BenchmarkOneToNone"}},
    60  		"BenchmarkOneToTwo":  []*parse.Benchmark{{Name: "BenchmarkOneToTwo"}},
    61  		"BenchmarkTwoToOne": []*parse.Benchmark{
    62  			{Name: "BenchmarkTwoToOne"},
    63  			{Name: "BenchmarkTwoToOne"},
    64  		},
    65  		"BenchmarkTwoEach": []*parse.Benchmark{
    66  			{Name: "BenchmarkTwoEach", N: 0x12b},
    67  			{Name: "BenchmarkTwoEach", N: 0x22b},
    68  		},
    69  	}
    70  
    71  	after := parse.Set{
    72  		"BenchmarkOneEach":   []*parse.Benchmark{{Name: "BenchmarkOneEach", N: 0x11a}},
    73  		"BenchmarkNoneToOne": []*parse.Benchmark{{Name: "BenchmarkNoneToOne"}},
    74  		"BenchmarkTwoToOne":  []*parse.Benchmark{{Name: "BenchmarkTwoToOne"}},
    75  		"BenchmarkOneToTwo": []*parse.Benchmark{
    76  			{Name: "BenchmarkOneToTwo"},
    77  			{Name: "BenchmarkOneToTwo"},
    78  		},
    79  		"BenchmarkTwoEach": []*parse.Benchmark{
    80  			{Name: "BenchmarkTwoEach", N: 0x12a},
    81  			{Name: "BenchmarkTwoEach", N: 0x22a},
    82  		},
    83  	}
    84  
    85  	pairs, errs := Correlate(before, after)
    86  
    87  	// Fail to match: BenchmarkOneToNone, BenchmarkOneToTwo, BenchmarkTwoToOne.
    88  	// Correlate does not notice BenchmarkNoneToOne.
    89  	if len(errs) != 3 {
    90  		t.Errorf("Correlated expected 4 errors, got %d: %v", len(errs), errs)
    91  	}
    92  
    93  	// Want three correlated pairs: one BenchmarkOneEach, two BenchmarkTwoEach.
    94  	if len(pairs) != 3 {
    95  		t.Fatalf("Correlated expected 3 pairs, got %v", pairs)
    96  	}
    97  
    98  	for _, pair := range pairs {
    99  		if pair.Before.N&0xF != 0xb {
   100  			t.Errorf("unexpected Before in pair %s", pair)
   101  		}
   102  		if pair.After.N&0xF != 0xa {
   103  			t.Errorf("unexpected After in pair %s", pair)
   104  		}
   105  		if pair.Before.N>>4 != pair.After.N>>4 {
   106  			t.Errorf("mismatched pair %s", pair)
   107  		}
   108  	}
   109  }
   110  
   111  func TestBenchCmpSorting(t *testing.T) {
   112  	c := []BenchCmp{
   113  		{&parse.Benchmark{Name: "BenchmarkMuchFaster", NsPerOp: 10, Ord: 3}, &parse.Benchmark{Name: "BenchmarkMuchFaster", NsPerOp: 1}},
   114  		{&parse.Benchmark{Name: "BenchmarkSameB", NsPerOp: 5, Ord: 1}, &parse.Benchmark{Name: "BenchmarkSameB", NsPerOp: 5}},
   115  		{&parse.Benchmark{Name: "BenchmarkSameA", NsPerOp: 5, Ord: 2}, &parse.Benchmark{Name: "BenchmarkSameA", NsPerOp: 5}},
   116  		{&parse.Benchmark{Name: "BenchmarkSlower", NsPerOp: 10, Ord: 0}, &parse.Benchmark{Name: "BenchmarkSlower", NsPerOp: 11}},
   117  	}
   118  
   119  	// Test just one magnitude-based sort order; they are symmetric.
   120  	sort.Sort(ByDeltaNsPerOp(c))
   121  	want := []string{"BenchmarkMuchFaster", "BenchmarkSlower", "BenchmarkSameA", "BenchmarkSameB"}
   122  	have := []string{c[0].Name(), c[1].Name(), c[2].Name(), c[3].Name()}
   123  	if !reflect.DeepEqual(want, have) {
   124  		t.Errorf("ByDeltaNsOp incorrect sorting: want %v have %v", want, have)
   125  	}
   126  
   127  	sort.Sort(ByParseOrder(c))
   128  	want = []string{"BenchmarkSlower", "BenchmarkSameB", "BenchmarkSameA", "BenchmarkMuchFaster"}
   129  	have = []string{c[0].Name(), c[1].Name(), c[2].Name(), c[3].Name()}
   130  	if !reflect.DeepEqual(want, have) {
   131  		t.Errorf("ByParseOrder incorrect sorting: want %v have %v", want, have)
   132  	}
   133  }