package main import ( "fmt" "runtime" "testing" ) // BenchmarkStackDepth measures the impact of stack depth on the time it takes // to create a stack trace. func BenchmarkStackDepth(b *testing.B) { for d := 8; d <= 1024; d = d * 2 { b.Run(fmt.Sprintf("%d", d), func(b *testing.B) { callers := make([]uintptr, d) atStackDepth(d, func() { for i := 0; i < b.N; i++ { if n := runtime.Callers(0, callers); n != d { b.Fatalf("got=%d want=%d", n, d) } } }) }) } } // atStackDepth recursively calls itself until the number of stack frames // reaches the desired depth, and then calls fn. func atStackDepth(depth int, fn func()) { pcs := make([]uintptr, depth+10) n := runtime.Callers(1, pcs) if n > depth { panic("depth exceeded") } else if n < depth { atStackDepth(depth, fn) return } fn() } func BenchmarkFunctionSize(b *testing.B) { m := map[int]func(func()){ 1: dostuff1, 2: dostuff2, 4: dostuff4, 8: dostuff8, 16: dostuff16, 32: dostuff32, 64: dostuff64, 128: dostuff128, 256: dostuff256, } var callers = make([]uintptr, 32) for s := 1; s <= 256; s = s * 2 { b.Run(fmt.Sprintf("%d", s), func(b *testing.B) { m[s](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) //} //}) //}) } // dostuff is supposed to generate a bunch of machine code that will hopefully // be inlined into its callers. func dostuff() int { m := map[int]string{} m[0] = "foo" m[100] = "bar" return len(m) } func dostuff1(fn func()) { dostuff() fn() } func dostuff2(fn func()) { dostuff() dostuff() fn() } func dostuff4(fn func()) { dostuff() dostuff() dostuff() dostuff() fn() } func dostuff8(fn func()) { dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() fn() } func dostuff16(fn func()) { dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() fn() } func dostuff32(fn func()) { dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() fn() } func dostuff64(fn func()) { dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() fn() } func dostuff128(fn func()) { dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() fn() } func dostuff256(fn func()) { dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() dostuff() fn() }