benchmark.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package benchmark contains benchmarking bound functions for internal use.
  5. package benchmark
  6. import (
  7. "log"
  8. "time"
  9. )
  10. type Benchmarks interface {
  11. // It seems to be much faster to call a native function from Java
  12. // when there is already a native call earlier in the stack.
  13. // Run runs a named benchmark from a different thread, with
  14. // no native call prior in the stack.
  15. Run(name string, n int)
  16. // RunDirect runs a named benchmark directly, with the native
  17. // context from the call itself.
  18. RunDirect(name string, n int)
  19. // Callbacks for Go benchmarks
  20. NewI() I
  21. Noargs()
  22. Onearg(_ int)
  23. Oneret() int
  24. Ref(_ I)
  25. Manyargs(_, _, _, _, _, _, _, _, _, _ int)
  26. String(_ string)
  27. StringRetShort() string
  28. StringRetLong() string
  29. Slice(_ []byte)
  30. }
  31. type (
  32. I interface {
  33. F()
  34. }
  35. AnI struct {
  36. }
  37. )
  38. func (_ *AnI) F() {
  39. }
  40. func NewI() I {
  41. return new(AnI)
  42. }
  43. func runBenchmark(name string, f func(n int)) {
  44. // Run once for warmup
  45. f(1)
  46. n := 1000
  47. var dt time.Duration
  48. minDuration := 1 * time.Second
  49. for dt < minDuration {
  50. n *= 2
  51. t0 := time.Now()
  52. f(n)
  53. dt = time.Since(t0)
  54. }
  55. log.Printf("Benchmark%s %d %d ns/op\n", name, n, dt.Nanoseconds()/int64(n))
  56. }
  57. func runGoBenchmark(name string, f func()) {
  58. runBenchmark("Go"+name, func(n int) {
  59. for i := 0; i < n; i++ {
  60. f()
  61. }
  62. })
  63. runBenchmark("Go"+name+"Direct", func(n int) {
  64. done := make(chan struct{})
  65. go func() {
  66. for i := 0; i < n; i++ {
  67. f()
  68. }
  69. close(done)
  70. }()
  71. <-done
  72. })
  73. }
  74. func RunBenchmarks(b Benchmarks) {
  75. names := []string{
  76. "Empty",
  77. "Noargs",
  78. "Onearg",
  79. "Oneret",
  80. "Manyargs",
  81. "Refforeign",
  82. "Refgo",
  83. "StringShort",
  84. "StringLong",
  85. "StringShortUnicode",
  86. "StringLongUnicode",
  87. "StringRetShort",
  88. "StringRetLong",
  89. "SliceShort",
  90. "SliceLong",
  91. }
  92. for _, name := range names {
  93. runBenchmark("Foreign"+name, func(n int) {
  94. b.Run(name, n)
  95. })
  96. runBenchmark("Foreign"+name+"Direct", func(n int) {
  97. b.RunDirect(name, n)
  98. })
  99. }
  100. runGoBenchmark("Empty", func() {})
  101. runGoBenchmark("Noarg", func() { b.Noargs() })
  102. runGoBenchmark("Onearg", func() { b.Onearg(0) })
  103. runGoBenchmark("Oneret", func() { b.Oneret() })
  104. foreignRef := b.NewI()
  105. runGoBenchmark("Refforeign", func() { b.Ref(foreignRef) })
  106. goRef := NewI()
  107. runGoBenchmark("Refgo", func() { b.Ref(goRef) })
  108. runGoBenchmark("Manyargs", func() { b.Manyargs(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) })
  109. runGoBenchmark("StringShort", func() { b.String(ShortString) })
  110. runGoBenchmark("StringLong", func() { b.String(LongString) })
  111. runGoBenchmark("StringShortUnicode", func() { b.String(ShortStringUnicode) })
  112. runGoBenchmark("StringLongUnicode", func() { b.String(LongStringUnicode) })
  113. runGoBenchmark("StringRetShort", func() { b.StringRetShort() })
  114. runGoBenchmark("StringRetLong", func() { b.StringRetLong() })
  115. runGoBenchmark("SliceShort", func() { b.Slice(ShortSlice) })
  116. runGoBenchmark("SliceLong", func() { b.Slice(LongSlice) })
  117. }
  118. func Noargs() {
  119. }
  120. func Onearg(_ int) {
  121. }
  122. func Manyargs(_, _, _, _, _, _, _, _, _, _ int) {
  123. }
  124. func Oneret() int {
  125. return 0
  126. }
  127. func String(_ string) {
  128. }
  129. func StringRetShort() string {
  130. return ShortString
  131. }
  132. func StringRetLong() string {
  133. return LongString
  134. }
  135. func Slice(_ []byte) {
  136. }
  137. func Ref(_ I) {
  138. }
  139. var (
  140. ShortSlice = make([]byte, 10)
  141. LongSlice = make([]byte, 100000)
  142. )
  143. const (
  144. ShortString = "Hello, World!"
  145. 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!"
  146. ShortStringUnicode = "Hello, 世界!"
  147. 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, 世界!, 世界!"
  148. )