| // Copyright 2016 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 benchmark contains benchmarking bound functions for internal use. |
| package benchmark |
| |
| import ( |
| "log" |
| "time" |
| ) |
| |
| type Benchmarks interface { |
| // It seems to be much faster to call a native function from Java |
| // when there is already a native call earlier in the stack. |
| |
| // Run runs a named benchmark from a different thread, with |
| // no native call prior in the stack. |
| Run(name string, n int) |
| // RunDirect runs a named benchmark directly, with the native |
| // context from the call itself. |
| RunDirect(name string, n int) |
| |
| // Callbacks for Go benchmarks |
| NewI() I |
| Noargs() |
| Onearg(_ int) |
| Oneret() int |
| Ref(_ I) |
| Manyargs(_, _, _, _, _, _, _, _, _, _ int) |
| String(_ string) |
| StringRetShort() string |
| StringRetLong() string |
| Slice(_ []byte) |
| } |
| |
| type ( |
| I interface { |
| F() |
| } |
| |
| AnI struct { |
| } |
| ) |
| |
| func (_ *AnI) F() { |
| } |
| |
| func NewI() I { |
| return new(AnI) |
| } |
| |
| func runBenchmark(name string, f func(n int)) { |
| // Run once for warmup |
| f(1) |
| n := 1000 |
| var dt time.Duration |
| minDuration := 1 * time.Second |
| for dt < minDuration { |
| n *= 2 |
| t0 := time.Now() |
| f(n) |
| dt = time.Since(t0) |
| } |
| log.Printf("Benchmark%s %d %d ns/op\n", name, n, dt.Nanoseconds()/int64(n)) |
| } |
| |
| func runGoBenchmark(name string, f func()) { |
| runBenchmark("Go"+name, func(n int) { |
| for i := 0; i < n; i++ { |
| f() |
| } |
| }) |
| runBenchmark("Go"+name+"Direct", func(n int) { |
| done := make(chan struct{}) |
| go func() { |
| for i := 0; i < n; i++ { |
| f() |
| } |
| close(done) |
| }() |
| <-done |
| }) |
| } |
| |
| func RunBenchmarks(b Benchmarks) { |
| names := []string{ |
| "Empty", |
| "Noargs", |
| "Onearg", |
| "Oneret", |
| "Manyargs", |
| "Refforeign", |
| "Refgo", |
| "StringShort", |
| "StringLong", |
| "StringShortUnicode", |
| "StringLongUnicode", |
| "StringRetShort", |
| "StringRetLong", |
| "SliceShort", |
| "SliceLong", |
| } |
| for _, name := range names { |
| runBenchmark("Foreign"+name, func(n int) { |
| b.Run(name, n) |
| }) |
| runBenchmark("Foreign"+name+"Direct", func(n int) { |
| b.RunDirect(name, n) |
| }) |
| } |
| runGoBenchmark("Empty", func() {}) |
| runGoBenchmark("Noarg", func() { b.Noargs() }) |
| runGoBenchmark("Onearg", func() { b.Onearg(0) }) |
| runGoBenchmark("Oneret", func() { b.Oneret() }) |
| foreignRef := b.NewI() |
| runGoBenchmark("Refforeign", func() { b.Ref(foreignRef) }) |
| goRef := NewI() |
| runGoBenchmark("Refgo", func() { b.Ref(goRef) }) |
| runGoBenchmark("Manyargs", func() { b.Manyargs(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }) |
| runGoBenchmark("StringShort", func() { b.String(ShortString) }) |
| runGoBenchmark("StringLong", func() { b.String(LongString) }) |
| runGoBenchmark("StringShortUnicode", func() { b.String(ShortStringUnicode) }) |
| runGoBenchmark("StringLongUnicode", func() { b.String(LongStringUnicode) }) |
| runGoBenchmark("StringRetShort", func() { b.StringRetShort() }) |
| runGoBenchmark("StringRetLong", func() { b.StringRetLong() }) |
| runGoBenchmark("SliceShort", func() { b.Slice(ShortSlice) }) |
| runGoBenchmark("SliceLong", func() { b.Slice(LongSlice) }) |
| } |
| |
| func Noargs() { |
| } |
| |
| func Onearg(_ int) { |
| } |
| |
| func Manyargs(_, _, _, _, _, _, _, _, _, _ int) { |
| } |
| |
| func Oneret() int { |
| return 0 |
| } |
| |
| func String(_ string) { |
| } |
| |
| func StringRetShort() string { |
| return ShortString |
| } |
| |
| func StringRetLong() string { |
| return LongString |
| } |
| |
| func Slice(_ []byte) { |
| } |
| |
| func Ref(_ I) { |
| } |
| |
| var ( |
| ShortSlice = make([]byte, 10) |
| LongSlice = make([]byte, 100000) |
| ) |
| |
| const ( |
| ShortString = "Hello, World!" |
| LongString = "Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!, World!" |
| ShortStringUnicode = "Hello, 世界!" |
| LongStringUnicode = "Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界! Hello, 世界!, 世界!" |
| ) |