Source File
benchmark.go
Belonging Package
testing
package testing
import (
)
func () {
matchBenchmarks = flag.String("test.bench", "", "run only benchmarks matching `regexp`")
benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks")
flag.Var(&benchTime, "test.benchtime", "run each benchmark for duration `d`")
}
var (
matchBenchmarks *string
benchmarkMemory *bool
benchTime = benchTimeFlag{d: 1 * time.Second} // changed during test of testing package
)
type benchTimeFlag struct {
d time.Duration
n int
}
func ( *benchTimeFlag) () string {
if .n > 0 {
return fmt.Sprintf("%dx", .n)
}
return time.Duration(.d).String()
}
func ( *benchTimeFlag) ( string) error {
if strings.HasSuffix(, "x") {
, := strconv.ParseInt([:len()-1], 10, 0)
if != nil || <= 0 {
return fmt.Errorf("invalid count")
}
* = benchTimeFlag{n: int()}
return nil
}
, := time.ParseDuration()
if != nil || <= 0 {
return fmt.Errorf("invalid duration")
}
* = benchTimeFlag{d: }
return nil
}
var benchmarkLock sync.Mutex
type InternalBenchmark struct {
Name string
F func(b *B)
}
type B struct {
common
importPath string // import path of the package containing the benchmark
context *benchContext
N int
previousN int // number of iterations in the previous run
previousDuration time.Duration // total duration of the previous run
benchFunc func(b *B)
benchTime benchTimeFlag
bytes int64
missingBytes bool // one of the subbenchmarks does not have bytes set.
timerOn bool
showAllocResult bool
result BenchmarkResult
func ( *B) () {
if !.timerOn {
runtime.ReadMemStats(&memStats)
.startAllocs = memStats.Mallocs
.startBytes = memStats.TotalAlloc
.start = time.Now()
.timerOn = true
}
}
func ( *B) () {
if .timerOn {
.duration += time.Since(.start)
runtime.ReadMemStats(&memStats)
.netAllocs += memStats.Mallocs - .startAllocs
.netBytes += memStats.TotalAlloc - .startBytes
.timerOn = false
}
}
func ( *B) () {
func ( *B) () {
.showAllocResult = true
}
func ( *B) ( int) {
benchmarkLock.Lock()
defer benchmarkLock.Unlock()
runtime.GC()
.raceErrors = -race.Errors()
.N =
.parallelism = 1
.ResetTimer()
.StartTimer()
.benchFunc()
.StopTimer()
.previousN =
.previousDuration = .duration
.raceErrors += race.Errors()
if .raceErrors > 0 {
.Errorf("race detected during execution of benchmark")
}
}
func (, int64) int64 {
if > {
return
}
return
}
func (, int64) int64 {
if < {
return
}
return
}
.context.processBench() // Must call doBench.
:= .Nanoseconds()
:= int64(.N)
:= .duration.Nanoseconds()
= 1
func ( BenchmarkResult) () int64 {
if , := .Extra["ns/op"]; {
return int64()
}
if .N <= 0 {
return 0
}
return .T.Nanoseconds() / int64(.N)
}
var string
switch := math.Abs(); {
case == 0 || >= 999.95:
= "%10.0f %s"
case >= 99.995:
= "%12.1f %s"
case >= 9.9995:
= "%13.2f %s"
case >= 0.99995:
= "%14.3f %s"
case >= 0.099995:
= "%15.4f %s"
case >= 0.0099995:
= "%16.5f %s"
case >= 0.00099995:
= "%17.6f %s"
default:
= "%18.7f %s"
}
fmt.Fprintf(, , , )
}
func ( BenchmarkResult) () string {
return fmt.Sprintf("%8d B/op\t%8d allocs/op",
.AllocedBytesPerOp(), .AllocsPerOp())
}
func ( func(, string) (bool, error), []InternalBenchmark) {
runBenchmarks("", , )
}
if len(*matchBenchmarks) == 0 {
return true
:= 1
for , := range cpuList {
if > {
=
}
}
:= &benchContext{
match: newMatcher(, *matchBenchmarks, "-test.bench"),
extLen: len(benchmarkName("", )),
}
var []InternalBenchmark
for , := range {
if , , := .match.fullName(nil, .Name); {
= append(, )
:= benchmarkName(.Name, )
if := len() + .extLen + 1; > .maxLen {
.maxLen =
}
}
}
:= &B{
common: common{
name: "Main",
w: os.Stdout,
bench: true,
},
importPath: ,
benchFunc: func( *B) {
for , := range {
.Run(.Name, .F)
}
},
benchTime: benchTime,
context: ,
}
if Verbose() {
.chatty = newChattyPrinter(.w)
}
.runN(1)
return !.failed
}
func ( *benchContext) ( *B) {
for , := range cpuList {
for := uint(0); < *count; ++ {
runtime.GOMAXPROCS()
:= benchmarkName(.name, )
atomic.StoreInt32(&.hasSub, 1)
benchmarkLock.Unlock()
defer benchmarkLock.Lock()
, , := .name, true, false
if .context != nil {
, , = .context.match.fullName(&.common, )
}
if ! {
return true
}
var [maxStackLen]uintptr
:= runtime.Callers(2, [:])
:= &B{
common: common{
signal: make(chan bool),
name: ,
parent: &.common,
level: .level + 1,
creator: [:],
w: .w,
chatty: .chatty,
bench: true,
},
importPath: .importPath,
benchFunc: ,
benchTime: .benchTime,
context: .context,
}
atomic.StoreInt32(&.hasSub, 1)
}
if .chatty != nil {
labelsOnce.Do(func() {
fmt.Printf("goos: %s\n", runtime.GOOS)
fmt.Printf("goarch: %s\n", runtime.GOARCH)
if .importPath != "" {
fmt.Printf("pkg: %s\n", .importPath)
}
if := sysinfo.CPU.Name(); != "" {
fmt.Printf("cpu: %s\n", )
}
})
fmt.Println()
}
if .run1() {
.run()
}
.add(.result)
return !.failed
}
func ( *B) ( BenchmarkResult) {
.missingBytes = true
.Bytes = 0
}
if !.missingBytes {
.Bytes += .Bytes
}
.MemAllocs += uint64(.AllocsPerOp())
.MemBytes += uint64(.AllocedBytesPerOp())
}
:= uint64(0)
if .previousN > 0 && .previousDuration > 0 {
= 1e5 * uint64(.previousN) / uint64(.previousDuration)
}
if < 1 {
= 1
if > 1e4 {
= 1e4
}
:= uint64(0)
:= .parallelism * runtime.GOMAXPROCS(0)
var sync.WaitGroup
.Add()
for := 0; < ; ++ {
go func() {
defer .Done()
:= &PB{
globalN: &,
grain: ,
bN: uint64(.N),
}
()
}()
}
.Wait()
if <= uint64(.N) && !.Failed() {
.Fatal("RunParallel: body exited without pb.Next() == false")
}
}
func ( *B) ( int) {
if >= 1 {
.parallelism =
}
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |