Welcome to our deep dive into Go Testing Benchmarks! In this lesson, we'll explore how to measure the performance of your Go functions using benchmarks. Let's get started! 📝
Benchmarks are a way to measure the performance of your Go code. They help you understand how fast your functions run, which is crucial for optimizing your code in real-world applications.
To create a benchmark, you'll need to define a func with the benchmark package. Here's a simple example:
package main
import (
"fmt"
"testing"
"time"
)
func BenchmarkSum(b *testing.B) {
for n := 0; n < b.N; n++ {
sum := 0
for i := 0; i < 100; i++ {
sum += i
}
// Uncomment the line below to see the performance for each run
// fmt.Println(sum)
}
}In the example above, we've defined a function BenchmarkSum that calculates the sum of numbers from 0 to 99. The b *testing.B parameter contains information about the benchmark, such as the number of iterations to run.
To run the benchmark, simply execute the go test command in your terminal:
go testGo will run the benchmark multiple times, calculate the average, and output the results. Here's an example output:
BenchmarkSum-8 1000000 1376 ns/op 200 B/op 6 allocs/opThe output shows the number of operations per second (ns/op), the amount of memory allocated per operation (B/op), and the number of allocations (allocs/op).
The benchmark output consists of three main parts:
BenchmarkSum-8: This is the name of the benchmark. The number after Benchmark (8 in this case) is called the N value. It determines how many times the function is run during each iteration.
1000000: This is the number of operations per second. The higher the number, the faster the function.
1376 ns/op: This is the average time taken to complete one operation. The lower the number, the faster the function.
Once you have a benchmark, you can optimize your code to improve performance. Let's optimize the Sum function by using the built-in math/big package to handle large numbers:
package main
import (
"fmt"
"math/big"
"testing"
"time"
)
func BenchmarkSumBig(b *testing.B) {
n := big.NewInt(0)
for n.SetString("0", b.N.String())
for n.Sub(n, big.NewInt(1)) ; n.Cmp(big.NewInt(0)) > 0; n.Sub(n, big.NewInt(1)) {
n.Add(n, big.NewInt(n.Int64()))
}
// Uncomment the line below to see the performance for each run
// fmt.Println(n)
}Now let's run the benchmark and compare the results:
go testThe output will show the performance of the optimized SumBig function. You'll notice that the performance improves significantly for larger numbers.
What is the purpose of a Go benchmark?