Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(701)

Side by Side Diff: src/pkg/testing/benchmark.go

Issue 154173: code review 154173: Adds benchmark support to gotest. (Closed)
Patch Set: code review 154173: Adds benchmark support to gotest. Created 15 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2009 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 testing
6
7 import (
8 "flag";
9 "fmt";
10 "math";
11 "os";
12 "time";
13 )
14
15 var matchBenchmarks = flag.String("benchmarks", "", "regular expression to selec t benchmarks to run")
16
17 // An internal type but exported because it is cross-package; part of the implem entation
18 // of gotest.
19 type Benchmark struct {
20 Name string;
21 F func(b *B);
22 }
23
24 // B is a type passed to Benchmark functions to manage benchmark
25 // timing and to specify the number of iterations to run.
26 type B struct {
27 N int;
28 benchmark Benchmark;
29 ns int64;
30 start int64;
31 }
32
33 // StartTimer starts timing a test. This function is called automatically
34 // before a benchmark starts, but it can also used to resume timing after
35 // a call to StopTimer.
36 func (b *B) StartTimer() { b.start = time.Nanoseconds() }
37
38 // StopTimer stops timing a test. This can be used to pause the timer
39 // while performing complex initialization that you don't
40 // want to measure.
41 func (b *B) StopTimer() {
42 if b.start > 0 {
43 b.ns += time.Nanoseconds() - b.start
44 }
45 b.start = 0;
46 }
47
48 // ResetTimer stops the timer and sets the elapsed benchmark time to zero.
49 func (b *B) ResetTimer() {
50 b.start = 0;
51 b.ns = 0;
52 }
53
54 func (b *B) nsPerOp() int64 {
55 if b.N <= 0 {
56 return 0
57 }
58 return b.ns / int64(b.N);
59 }
60
61 // runN runs a single benchmark for the specified number of iterations (n).
rsc 2009/11/18 07:16:49 can drop (n)
trevor.strohman 2009/11/18 16:54:51 Done.
62 func (b *B) runN(n int) {
63 b.N = n;
64 b.ResetTimer();
65 b.StartTimer();
66 b.benchmark.F(b);
67 b.StopTimer();
68 }
69
70 func min(x, y int) int {
71 if x > y {
72 return y
73 }
74 return x;
75 }
76
77 // roundDown10 rounds a number down to the nearest power of 10.
78 func roundDown10(n int) int { return int(math.Pow10(int(math.Log10(float64(n ))))) }
79
80 // roundUp rounds x up to a number of the form [1eX, 2eX, 5eX].
81 func roundUp(n int) int {
82 base := roundDown10(n);
83 if n < (2 * base) {
84 return 2 * base
85 }
86 if n < (5 * base) {
87 return 5 * base
88 }
89 return 10 * base;
90 }
91
92 // run times the benchmark function. It gradually increases the number
93 // of benchmark iterations until the benchmark runs for a second in order
94 // to get a reasonable measurement. It prints timing information in this form
95 // testing.BenchmarkHello 100000 19 ns/op
96 func (b *B) run() {
97 // Run the benchmark for a single iteration in case it's expensive.
98 n := 1;
99 b.runN(n);
100 // Run the benchmark for at least a second.
101 for b.ns < 1e9 && n < 1e9 {
102 last := n;
103 // Predict iterations/sec.
104 if b.nsPerOp() == 0 {
105 n = 1e9
106 } else {
107 n = 1e9 / int(b.nsPerOp())
108 }
109 // Run more iterations than we think we'll need for a second (1. 5x).
110 // Don't grow too fast in case we had timing errors previously.
111 n = min(int(1.5*float(n)), 100*last);
112 // Round up to something easy to read.
113 n = roundUp(n);
114 b.runN(n);
115 }
116 fmt.Printf("%s\t%d\t%10d ns/op\n", b.benchmark.Name, b.N, b.nsPerOp());
117 }
118
119 // An internal function but exported because it is cross-package; part of the im plementation
120 // of gotest.
121 func RunBenchmarks(benchmarks []Benchmark) {
122 // If no flag was specified, don't run benchmarks.
123 if len(*matchBenchmarks) == 0 {
124 return
125 }
126 re, err := CompileRegexp(*matchBenchmarks);
127 if err != "" {
128 println("invalid regexp for -benchmarks:", err);
129 os.Exit(1);
130 }
131 for _, Benchmark := range benchmarks {
132 if !re.MatchString(Benchmark.Name) {
133 continue
134 }
135 b := &B{benchmark: Benchmark};
136 b.run();
137 }
138 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b