Benchmarks

Benchmarking is another useful feature of the golang testing standard library. It allows us to conduct performance tests for the parts of our code where being fast matters most. That will help us ensure that we don't cause performance regressions when we are making changes.

Benchmarks are very similar to tests. If you replace Test with Benchmark and testing.T with testing.B, you're 90% of the way there.

The other 10% is that you'll need to write a for loop around whatever you're trying to benchmark. testing.B provides a parameter, N, which determines the number of loops to do over the benchmarked function. A very short benchmarking function might look like this:

Let's set up a Get benchmark since the Get function is a very critical path in a key-value store. We want it to be fast and remain fast in the future.

In order to make our benchmark we're going to copy the entirety of our TestGet method and make some small changes. BenchmarkGet will look exactly like TestGet, except we remove the t.Parallel() call, rename the function to BenchmarkGet, and change t *testing.T to b *testing.B.

The reason we are copying TestGet rather than coming up with a common set of abstractions and using them in both functions, is because we actually expect these functions to differ greatly over time. TestGet will likely receive a large number of varried test cases, some added as bugs are discovered and some added to help ensure the function will work as intended with new keys and values. BenchmarkGet, however, is likely to remain very stable, and will only need to be adjusted for significant changes made to the Get function. So copying everything allows us to more easily write BenchmarkGet while preventing a tight coupling of these two functions that are currently similar but will likely be very different in the future.

 

This page is a preview of Reliable Webservers with Go

Please select a discussion on the left.