Performance and Benchmarking Basics
Benchmark Table
Go benchmarks produce rows that compare operations with numbers such as nanoseconds per operation.
benchmark result
Static examples can model benchmark output as data so the lesson explains interpretation without timing the host machine.
Benchmark Table
benchmark_table.go
Replay: real traced execution (multi-file project)
package main
import "fmt"
type BenchRow struct {
Name string
NsOp int
Allocs int
}
func main() {
var nsOp = 80
row := BenchRow{Name: "BenchmarkLookup", NsOp: nsOp, Allocs: 0}
fastEnough := row.NsOp <= 100
allocationFree := row.Allocs == 0
fmt.Println("name=", row.Name)
fmt.Println("ns_per_op=", row.NsOp)
fmt.Println("allocs=", row.Allocs)
fmt.Println("fast_enough=", fastEnough)
fmt.Println("allocation_free=", allocationFree)
}
package main
import "fmt"
type BenchRow struct {
Name string
NsOp int
Allocs int
}
func main() {
var nsOp = 40
row := BenchRow{Name: "BenchmarkLookup", NsOp: nsOp, Allocs: 0}
fastEnough := row.NsOp <= 100
allocationFree := row.Allocs == 0
fmt.Println("name=", row.Name)
fmt.Println("ns_per_op=", row.NsOp)
fmt.Println("allocs=", row.Allocs)
fmt.Println("fast_enough=", fastEnough)
fmt.Println("allocation_free=", allocationFree)
}
package main
import "fmt"
type BenchRow struct {
Name string
NsOp int
Allocs int
}
func main() {
var nsOp = 120
row := BenchRow{Name: "BenchmarkLookup", NsOp: nsOp, Allocs: 0}
fastEnough := row.NsOp <= 100
allocationFree := row.Allocs == 0
fmt.Println("name=", row.Name)
fmt.Println("ns_per_op=", row.NsOp)
fmt.Println("allocs=", row.Allocs)
fmt.Println("fast_enough=", fastEnough)
fmt.Println("allocation_free=", allocationFree)
}
nsOp ← 80, row ← main.BenchRow{Name:"BenchmarkLookup", NsOp:80, Allocs:0}
11func main() {12 var nsOp→ 80 = 80 //@nsOp=40, 12013 row→ main.BenchRow{Name:"BenchmarkLookup", NsOp:80, Allocs:0} := BenchRow{Name: "BenchmarkLookup", NsOp: nsOp80, Allocs: 0}14 fastEnough→ true := row.NsOp80 <= 10015 allocationFree→ true := row.Allocs0 == 01617 fmt.Println("name=", row.Name"BenchmarkLookup")18 fmt.Println("ns_per_op=", row.NsOp80)19 fmt.Println("allocs=", row.Allocs0)20 fmt.Println("fast_enough=", fastEnoughtrue)21 fmt.Println("allocation_free=", allocationFreetrue)22}outputname= BenchmarkLookup ns_per_op= 80 allocs= 0 fast_enough= true allocation_free= true
nsOp ← 40, row ← main.BenchRow{Name:"BenchmarkLookup", NsOp:40, Allocs:0}
11func main() {12 var nsOp→ 40 = 4013 row→ main.BenchRow{Name:"BenchmarkLookup", NsOp:40, Allocs:0} := BenchRow{Name: "BenchmarkLookup", NsOp: nsOp40, Allocs: 0}14 fastEnough→ true := row.NsOp40 <= 10015 allocationFree→ true := row.Allocs0 == 01617 fmt.Println("name=", row.Name"BenchmarkLookup")18 fmt.Println("ns_per_op=", row.NsOp40)19 fmt.Println("allocs=", row.Allocs0)20 fmt.Println("fast_enough=", fastEnoughtrue)21 fmt.Println("allocation_free=", allocationFreetrue)22}outputname= BenchmarkLookup ns_per_op= 40 allocs= 0 fast_enough= true allocation_free= true
nsOp ← 120, row ← main.BenchRow{Name:"BenchmarkLookup", NsOp:120, Allocs:0}
11func main() {12 var nsOp→ 120 = 12013 row→ main.BenchRow{Name:"BenchmarkLookup", NsOp:120, Allocs:0} := BenchRow{Name: "BenchmarkLookup", NsOp: nsOp120, Allocs: 0}14 fastEnough→ false := row.NsOp120 <= 10015 allocationFree→ true := row.Allocs0 == 01617 fmt.Println("name=", row.Name"BenchmarkLookup")18 fmt.Println("ns_per_op=", row.NsOp120)19 fmt.Println("allocs=", row.Allocs0)20 fmt.Println("fast_enough=", fastEnoughfalse)21 fmt.Println("allocation_free=", allocationFreetrue)22}outputname= BenchmarkLookup ns_per_op= 120 allocs= 0 fast_enough= false allocation_free= true