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 | } |
134 |
Members