diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-08-03 16:54:30 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-08-03 16:54:30 +0200 |
commit | 28592ee1ea1f5cdffcf85472f9de0285d928cf12 (patch) | |
tree | 32944e18b23f7fe4a0818a694aa2a6dfb1835463 /src/pkg/testing/benchmark.go | |
parent | e836bee4716dc0d4d913537ad3ad1925a7ac32d0 (diff) | |
download | golang-upstream/59.tar.gz |
Imported Upstream version 59upstream/59
Diffstat (limited to 'src/pkg/testing/benchmark.go')
-rw-r--r-- | src/pkg/testing/benchmark.go | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/src/pkg/testing/benchmark.go b/src/pkg/testing/benchmark.go index f8b53e63a..3b416acfa 100644 --- a/src/pkg/testing/benchmark.go +++ b/src/pkg/testing/benchmark.go @@ -13,6 +13,7 @@ import ( ) var matchBenchmarks = flag.String("test.bench", "", "regular expression to select benchmarks to run") +var benchTime = flag.Float64("test.benchtime", 1, "approximate run time for each benchmark, in seconds") // An internal type but exported because it is cross-package; part of the implementation // of gotest. @@ -34,7 +35,11 @@ type B struct { // StartTimer starts timing a test. This function is called automatically // before a benchmark starts, but it can also used to resume timing after // a call to StopTimer. -func (b *B) StartTimer() { b.start = time.Nanoseconds() } +func (b *B) StartTimer() { + if b.start == 0 { + b.start = time.Nanoseconds() + } +} // StopTimer stops timing a test. This can be used to pause the timer // while performing complex initialization that you don't @@ -46,9 +51,12 @@ func (b *B) StopTimer() { b.start = 0 } -// ResetTimer stops the timer and sets the elapsed benchmark time to zero. +// ResetTimer sets the elapsed benchmark time to zero. +// It does not affect whether the timer is running. func (b *B) ResetTimer() { - b.start = 0 + if b.start > 0 { + b.start = time.Nanoseconds() + } b.ns = 0 } @@ -125,14 +133,15 @@ func (b *B) run() BenchmarkResult { // Run the benchmark for a single iteration in case it's expensive. n := 1 b.runN(n) - // Run the benchmark for at least a second. - for b.ns < 1e9 && n < 1e9 { + // Run the benchmark for at least the specified amount of time. + time := int64(*benchTime * 1e9) + for b.ns < time && n < 1e9 { last := n // Predict iterations/sec. if b.nsPerOp() == 0 { n = 1e9 } else { - n = 1e9 / int(b.nsPerOp()) + n = int(time / b.nsPerOp()) } // Run more iterations than we think we'll need for a second (1.5x). // Don't grow too fast in case we had timing errors previously. @@ -172,7 +181,18 @@ func (r BenchmarkResult) String() string { if mbs != 0 { mb = fmt.Sprintf("\t%7.2f MB/s", mbs) } - return fmt.Sprintf("%8d\t%10d ns/op%s", r.N, r.NsPerOp(), mb) + nsop := r.NsPerOp() + ns := fmt.Sprintf("%10d ns/op", nsop) + if r.N > 0 && nsop < 100 { + // The format specifiers here make sure that + // the ones digits line up for all three possible formats. + if nsop < 10 { + ns = fmt.Sprintf("%13.2f ns/op", float64(r.Ns)/float64(r.N)) + } else { + ns = fmt.Sprintf("%12.1f ns/op", float64(r.Ns)/float64(r.N)) + } + } + return fmt.Sprintf("%8d\t%s%s", r.N, ns, mb) } // An internal function but exported because it is cross-package; part of the implementation @@ -182,7 +202,6 @@ func RunBenchmarks(matchString func(pat, str string) (bool, os.Error), benchmark if len(*matchBenchmarks) == 0 { return } - procs := runtime.GOMAXPROCS(-1) for _, Benchmark := range benchmarks { matched, err := matchString(*matchBenchmarks, Benchmark.Name) if err != nil { @@ -192,14 +211,19 @@ func RunBenchmarks(matchString func(pat, str string) (bool, os.Error), benchmark if !matched { continue } - b := &B{benchmark: Benchmark} - r := b.run() - print(fmt.Sprintf("%s\t%v\n", Benchmark.Name, r)) - if p := runtime.GOMAXPROCS(-1); p != procs { - print(fmt.Sprintf("%s left GOMAXPROCS set to %d\n", Benchmark.Name, p)) - procs = p + for _, procs := range cpuList { + runtime.GOMAXPROCS(procs) + b := &B{benchmark: Benchmark} + r := b.run() + benchName := Benchmark.Name + if procs != 1 { + benchName = fmt.Sprintf("%s-%d", Benchmark.Name, procs) + } + print(fmt.Sprintf("%s\t%v\n", benchName, r)) + if p := runtime.GOMAXPROCS(-1); p != procs { + print(fmt.Sprintf("%s left GOMAXPROCS set to %d\n", benchName, p)) + } } - } } |