callers-func-length

This commit is contained in:
Felix Geisendörfer 2021-04-03 12:47:19 +02:00
parent 4a4828f120
commit f8f6e88e3a
4 changed files with 191 additions and 0 deletions

View file

@ -0,0 +1,14 @@
# callers-func-length
A simple benchmark that shows that the costs of stack unwinding in Go increase for larger functions. This is due to the way `gopclntab` based unwinding is implemented.
```
go test -bench .
goos: darwin
goarch: amd64
pkg: github.com/felixge/go-profiler-notes/examples/callers-func-length
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkCallers/short-12 2623002 454.1 ns/op
BenchmarkCallers/loop-12 2590384 466.8 ns/op
BenchmarkCallers/long-12 638096 1862 ns/op
```

View file

@ -0,0 +1,3 @@
module github.com/felixge/go-profiler-notes/examples/callers-func-length
go 1.16

View file

@ -0,0 +1,17 @@
package main
import (
"fmt"
"os"
)
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run() error {
return nil
}

View file

@ -0,0 +1,157 @@
package main
import (
"runtime"
"testing"
)
var callers = make([]uintptr, 32)
func BenchmarkCallers(b *testing.B) {
b.Run("short", func(b *testing.B) {
short(func() {
for i := 0; i < b.N; i++ {
runtime.Callers(0, callers)
}
})
})
b.Run("loop", func(b *testing.B) {
loop(func() {
for i := 0; i < b.N; i++ {
runtime.Callers(0, callers)
}
})
})
b.Run("long", func(b *testing.B) {
long(func() {
for i := 0; i < b.N; i++ {
runtime.Callers(0, callers)
}
})
})
}
func short(fn func()) {
other()
fn()
}
func loop(fn func()) {
for i := 0; i < 1000; i++ {
other()
}
fn()
}
func long(fn func()) {
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
other()
fn()
}
func other() int {
m := map[int]string{}
m[0] = "foo"
m[100] = "bar"
return len(m)
}