2013-05-31 07:03:22 -06:00
|
|
|
// Copyright 2013 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package testing_test
|
|
|
|
|
|
|
|
import (
|
2014-02-16 19:29:56 -07:00
|
|
|
"bytes"
|
|
|
|
"runtime"
|
|
|
|
"sync/atomic"
|
2013-05-31 07:03:22 -06:00
|
|
|
"testing"
|
2014-02-16 19:29:56 -07:00
|
|
|
"text/template"
|
2013-05-31 07:03:22 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
var roundDownTests = []struct {
|
|
|
|
v, expected int
|
|
|
|
}{
|
|
|
|
{1, 1},
|
|
|
|
{9, 1},
|
2013-06-01 17:13:12 -06:00
|
|
|
{10, 10},
|
2013-05-31 07:03:22 -06:00
|
|
|
{11, 10},
|
2013-06-01 17:13:12 -06:00
|
|
|
{100, 100},
|
|
|
|
{101, 100},
|
|
|
|
{999, 100},
|
|
|
|
{1000, 1000},
|
|
|
|
{1001, 1000},
|
2013-05-31 07:03:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestRoundDown10(t *testing.T) {
|
|
|
|
for _, tt := range roundDownTests {
|
|
|
|
actual := testing.RoundDown10(tt.v)
|
|
|
|
if tt.expected != actual {
|
2013-06-01 17:13:12 -06:00
|
|
|
t.Errorf("roundDown10(%d): expected %d, actual %d", tt.v, tt.expected, actual)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var roundUpTests = []struct {
|
|
|
|
v, expected int
|
|
|
|
}{
|
|
|
|
{0, 1},
|
|
|
|
{1, 1},
|
|
|
|
{2, 2},
|
testing: make benchmarking faster
The number of estimated iterations required to reach the benchtime is multiplied by a safety margin (to avoid falling just short) and then rounded up to a readable number. With an accurate estimate, in the worse case, the resulting number of iterations could be 3.75x more than necessary: 1.5x for safety * 2.5x to round up (e.g. from 2eX+1 to 5eX).
This CL reduces the safety margin to 1.2x. Experimentation showed a diminishing margin of return past 1.2x, although the average case continued to show improvements down to 1.05x.
This CL also reduces the maximum round-up multiplier from 2.5x (from 2eX+1 to 5eX) to 2x, by allowing the number of iterations to be of the form 3eX.
Both changes improve benchmark wall clock times, and the effects are cumulative.
From 1.5x to 1.2x safety margin:
package old s new s delta
bytes 163 125 -23%
encoding/json 27 21 -22%
net/http 42 36 -14%
runtime 463 418 -10%
strings 82 65 -21%
Allowing 3eX iterations:
package old s new s delta
bytes 163 134 -18%
encoding/json 27 23 -15%
net/http 42 36 -14%
runtime 463 422 -9%
strings 82 72 -12%
Combined:
package old s new s delta
bytes 163 112 -31%
encoding/json 27 20 -26%
net/http 42 30 -29%
runtime 463 346 -25%
strings 82 60 -27%
LGTM=crawshaw, r, rsc
R=golang-codereviews, crawshaw, r, rsc
CC=golang-codereviews
https://golang.org/cl/105990045
2014-06-24 09:39:30 -06:00
|
|
|
{3, 3},
|
2013-06-01 17:13:12 -06:00
|
|
|
{5, 5},
|
|
|
|
{9, 10},
|
|
|
|
{999, 1000},
|
|
|
|
{1000, 1000},
|
|
|
|
{1400, 2000},
|
|
|
|
{1700, 2000},
|
testing: make benchmarking faster
The number of estimated iterations required to reach the benchtime is multiplied by a safety margin (to avoid falling just short) and then rounded up to a readable number. With an accurate estimate, in the worse case, the resulting number of iterations could be 3.75x more than necessary: 1.5x for safety * 2.5x to round up (e.g. from 2eX+1 to 5eX).
This CL reduces the safety margin to 1.2x. Experimentation showed a diminishing margin of return past 1.2x, although the average case continued to show improvements down to 1.05x.
This CL also reduces the maximum round-up multiplier from 2.5x (from 2eX+1 to 5eX) to 2x, by allowing the number of iterations to be of the form 3eX.
Both changes improve benchmark wall clock times, and the effects are cumulative.
From 1.5x to 1.2x safety margin:
package old s new s delta
bytes 163 125 -23%
encoding/json 27 21 -22%
net/http 42 36 -14%
runtime 463 418 -10%
strings 82 65 -21%
Allowing 3eX iterations:
package old s new s delta
bytes 163 134 -18%
encoding/json 27 23 -15%
net/http 42 36 -14%
runtime 463 422 -9%
strings 82 72 -12%
Combined:
package old s new s delta
bytes 163 112 -31%
encoding/json 27 20 -26%
net/http 42 30 -29%
runtime 463 346 -25%
strings 82 60 -27%
LGTM=crawshaw, r, rsc
R=golang-codereviews, crawshaw, r, rsc
CC=golang-codereviews
https://golang.org/cl/105990045
2014-06-24 09:39:30 -06:00
|
|
|
{2700, 3000},
|
2013-06-01 17:13:12 -06:00
|
|
|
{4999, 5000},
|
|
|
|
{5000, 5000},
|
|
|
|
{5001, 10000},
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRoundUp(t *testing.T) {
|
|
|
|
for _, tt := range roundUpTests {
|
|
|
|
actual := testing.RoundUp(tt.v)
|
|
|
|
if tt.expected != actual {
|
|
|
|
t.Errorf("roundUp(%d): expected %d, actual %d", tt.v, tt.expected, actual)
|
2013-05-31 07:03:22 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-02-16 19:29:56 -07:00
|
|
|
|
|
|
|
func TestRunParallel(t *testing.T) {
|
|
|
|
testing.Benchmark(func(b *testing.B) {
|
|
|
|
procs := uint32(0)
|
|
|
|
iters := uint64(0)
|
|
|
|
b.SetParallelism(3)
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
atomic.AddUint32(&procs, 1)
|
|
|
|
for pb.Next() {
|
|
|
|
atomic.AddUint64(&iters, 1)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
if want := uint32(3 * runtime.GOMAXPROCS(0)); procs != want {
|
|
|
|
t.Errorf("got %v procs, want %v", procs, want)
|
|
|
|
}
|
|
|
|
if iters != uint64(b.N) {
|
|
|
|
t.Errorf("got %v iters, want %v", iters, b.N)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRunParallelFail(t *testing.T) {
|
|
|
|
testing.Benchmark(func(b *testing.B) {
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
// The function must be able to log/abort
|
|
|
|
// w/o crashing/deadlocking the whole benchmark.
|
|
|
|
b.Log("log")
|
|
|
|
b.Error("error")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func ExampleB_RunParallel() {
|
|
|
|
// Parallel benchmark for text/template.Template.Execute on a single object.
|
|
|
|
testing.Benchmark(func(b *testing.B) {
|
|
|
|
templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
|
|
|
|
// RunParallel will create GOMAXPROCS goroutines
|
|
|
|
// and distribute work among them.
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
// Each goroutine has its own bytes.Buffer.
|
|
|
|
var buf bytes.Buffer
|
|
|
|
for pb.Next() {
|
|
|
|
// The loop body is executed b.N times total across all goroutines.
|
|
|
|
buf.Reset()
|
|
|
|
templ.Execute(&buf, "World")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|