go · level 3 · unit 7 · lesson 2
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
A runs your code b.N times and reports the cost.
A benchmark measures how fast code runs. testing.Benchmark takes a function with a b *testing.B, and your function runs the code b.N times in a loop. Go picks b.N itself, raising it until the timing is steady, then reports the time per operation in ns/op.
Speed is not the only cost. Each , a request for fresh memory, makes more work for Go's memory clean-up. b.ReportAllocs() records allocations too, and testing.AllocsPerRun counts them for a single function.
On your own computer, benchmarks live in _test.go files and run with go test -bench=.. For a whole program, a from pprof shows where the time really goes. Measure first: guesses about the slow part are often wrong.
package main
import (
"fmt"
"strings"
"testing"
)
func main() {
words := strings.Fields("the quick brown fox jumps over the lazy dog")
r := testing.Benchmark(func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
strings.Join(words, " ")
}
})
fmt.Println("ran", r.N > 0)
fmt.Println(r)
fmt.Println("allocations per join:", r.AllocsPerOp())
} Your numbers will differ from anyone else's, and from your own next run, so compare them and never copy them into a test.
guess first
Two ways to join nine words. What prints?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
package main
import (
"fmt"
"strings"
"testing"
)
func plus(words []string) string {
s := ""
for _, w := range words {
s += w
}
return s
}
func main() {
words := strings.Fields("the quick brown fox jumps over the lazy dog")
slow := testing.AllocsPerRun(100, func() { plus(words) })
fast := testing.AllocsPerRun(100, func() { strings.Join(words, "") })
fmt.Println(fast < slow, fast)
}
your turn
Your turn. Benchmark a laugh.
Fill in the field that holds how many times to run, then choose how many times to repeat ha. Your timing will differ every run.
output
press run to see what happens
fix it
Building the squares allocates too often. Can you fix it?
output
press run to see what happens
- Each time
appendruns out of room, it allocates a bigger slice and copies everything across. - You know from the start that there will be
nsquares, so ask for that much room once. - Start with
out := make([]int, 0, n)instead ofvar out []int.
nailed it
you measure before you optimise. :D
testing.Benchmarkruns your codeb.Ntimes and reportsns/op.- Fewer allocations usually means faster code.
- Use
go test -benchandpprofon your own computer.
new words in your collection
- benchmark
- allocation
- profile
This lesson isn’t saved. A free account remembers every lesson you finish.