~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/testing/benchmark.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
        "fmt"
10
10
        "os"
11
11
        "runtime"
 
12
        "sync"
12
13
        "time"
13
14
)
14
15
 
15
16
var matchBenchmarks = flag.String("test.bench", "", "regular expression to select benchmarks to run")
16
 
var benchTime = flag.Float64("test.benchtime", 1, "approximate run time for each benchmark, in seconds")
 
17
var benchTime = flag.Duration("test.benchtime", 1*time.Second, "approximate run time for each benchmark")
 
18
var benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks")
 
19
 
 
20
// Global lock to ensure only one benchmark runs at a time.
 
21
var benchmarkLock sync.Mutex
 
22
 
 
23
// Used for every benchmark for measuring memory.
 
24
var memStats runtime.MemStats
17
25
 
18
26
// An internal type but exported because it is cross-package; part of the implementation
19
27
// of the "go test" command.
26
34
// timing and to specify the number of iterations to run.
27
35
type B struct {
28
36
        common
29
 
        N         int
30
 
        benchmark InternalBenchmark
31
 
        bytes     int64
32
 
        timerOn   bool
33
 
        result    BenchmarkResult
 
37
        N               int
 
38
        benchmark       InternalBenchmark
 
39
        bytes           int64
 
40
        timerOn         bool
 
41
        showAllocResult bool
 
42
        result          BenchmarkResult
 
43
        // The initial states of memStats.Mallocs and memStats.TotalAlloc.
 
44
        startAllocs uint64
 
45
        startBytes  uint64
 
46
        // The net total of this test after being run.
 
47
        netAllocs uint64
 
48
        netBytes  uint64
34
49
}
35
50
 
36
51
// StartTimer starts timing a test.  This function is called automatically
38
53
// a call to StopTimer.
39
54
func (b *B) StartTimer() {
40
55
        if !b.timerOn {
 
56
                runtime.ReadMemStats(&memStats)
 
57
                b.startAllocs = memStats.Mallocs
 
58
                b.startBytes = memStats.TotalAlloc
41
59
                b.start = time.Now()
42
60
                b.timerOn = true
43
61
        }
49
67
func (b *B) StopTimer() {
50
68
        if b.timerOn {
51
69
                b.duration += time.Now().Sub(b.start)
 
70
                runtime.ReadMemStats(&memStats)
 
71
                b.netAllocs += memStats.Mallocs - b.startAllocs
 
72
                b.netBytes += memStats.TotalAlloc - b.startBytes
52
73
                b.timerOn = false
53
74
        }
54
75
}
57
78
// It does not affect whether the timer is running.
58
79
func (b *B) ResetTimer() {
59
80
        if b.timerOn {
 
81
                runtime.ReadMemStats(&memStats)
 
82
                b.startAllocs = memStats.Mallocs
 
83
                b.startBytes = memStats.TotalAlloc
60
84
                b.start = time.Now()
61
85
        }
62
86
        b.duration = 0
 
87
        b.netAllocs = 0
 
88
        b.netBytes = 0
63
89
}
64
90
 
65
91
// SetBytes records the number of bytes processed in a single operation.
66
92
// If this is called, the benchmark will report ns/op and MB/s.
67
93
func (b *B) SetBytes(n int64) { b.bytes = n }
68
94
 
 
95
// ReportAllocs enables malloc statistics for this benchmark.
 
96
// It is equivalent to setting -test.benchmem, but it only affects the
 
97
// benchmark function that calls ReportAllocs.
 
98
func (b *B) ReportAllocs() {
 
99
        b.showAllocResult = true
 
100
}
 
101
 
69
102
func (b *B) nsPerOp() int64 {
70
103
        if b.N <= 0 {
71
104
                return 0
75
108
 
76
109
// runN runs a single benchmark for the specified number of iterations.
77
110
func (b *B) runN(n int) {
 
111
        benchmarkLock.Lock()
 
112
        defer benchmarkLock.Unlock()
78
113
        // Try to get a comparable environment for each run
79
114
        // by clearing garbage from previous runs.
80
115
        runtime.GC()
151
186
 
152
187
        b.runN(n)
153
188
        // Run the benchmark for at least the specified amount of time.
154
 
        d := time.Duration(*benchTime * float64(time.Second))
 
189
        d := *benchTime
155
190
        for !b.failed && b.duration < d && n < 1e9 {
156
191
                last := n
157
192
                // Predict iterations/sec.
168
203
                n = roundUp(n)
169
204
                b.runN(n)
170
205
        }
171
 
        b.result = BenchmarkResult{b.N, b.duration, b.bytes}
 
206
        b.result = BenchmarkResult{b.N, b.duration, b.bytes, b.netAllocs, b.netBytes}
172
207
}
173
208
 
174
209
// The results of a benchmark run.
175
210
type BenchmarkResult struct {
176
 
        N     int           // The number of iterations.
177
 
        T     time.Duration // The total time taken.
178
 
        Bytes int64         // Bytes processed in one iteration.
 
211
        N         int           // The number of iterations.
 
212
        T         time.Duration // The total time taken.
 
213
        Bytes     int64         // Bytes processed in one iteration.
 
214
        MemAllocs uint64        // The total number of memory allocations.
 
215
        MemBytes  uint64        // The total number of bytes allocated.
179
216
}
180
217
 
181
218
func (r BenchmarkResult) NsPerOp() int64 {
192
229
        return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds()
193
230
}
194
231
 
 
232
func (r BenchmarkResult) AllocsPerOp() int64 {
 
233
        if r.N <= 0 {
 
234
                return 0
 
235
        }
 
236
        return int64(r.MemAllocs) / int64(r.N)
 
237
}
 
238
 
 
239
func (r BenchmarkResult) AllocedBytesPerOp() int64 {
 
240
        if r.N <= 0 {
 
241
                return 0
 
242
        }
 
243
        return int64(r.MemBytes) / int64(r.N)
 
244
}
 
245
 
195
246
func (r BenchmarkResult) String() string {
196
247
        mbs := r.mbPerSec()
197
248
        mb := ""
212
263
        return fmt.Sprintf("%8d\t%s%s", r.N, ns, mb)
213
264
}
214
265
 
 
266
func (r BenchmarkResult) MemString() string {
 
267
        return fmt.Sprintf("%8d B/op\t%8d allocs/op",
 
268
                r.AllocedBytesPerOp(), r.AllocsPerOp())
 
269
}
 
270
 
215
271
// An internal function but exported because it is cross-package; part of the implementation
216
272
// of the "go test" command.
217
273
func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) {
249
305
                                fmt.Printf("--- FAIL: %s\n%s", benchName, b.output)
250
306
                                continue
251
307
                        }
252
 
                        fmt.Printf("%v\n", r)
 
308
                        results := r.String()
 
309
                        if *benchmarkMemory || b.showAllocResult {
 
310
                                results += "\t" + r.MemString()
 
311
                        }
 
312
                        fmt.Println(results)
253
313
                        // Unlike with tests, we ignore the -chatty flag and always print output for
254
314
                        // benchmarks since the output generation time will skew the results.
255
315
                        if len(b.output) > 0 {