Introduction
From The Zen of Go:
If you think it’s slow, first prove it with a benchmark
Don’t assume if things are slow. Benchmark it and see if they are really slow.
One thing to note here is benchmarking a program is different from profiling a program.
Benchmarking is the way we check how fast our algorithm is for a given unit of the program. In benchmarking, we typically see how many iterations can a piece of code can run in a given time.
Profiling is more of a complete picture. Profiling can help determine which methods are called and how long each method takes to complete. Profiling also tell us a lot of valuable things, like what percentage of CPU time was use where, where memory was allocated and things like that. We can say benchmarking is part of profiling.
Today we’ll learn about benchmarking our function in Go. In meantime, please connect with me on LinkedIn
How to benchmark a function in Go
In Go, benchmarking is closely tied to the testing suite. This literally means you’ll write a benchmarking code in the same place you write your unit/integration tests.
If you are familiar with unit tests in Go already, you know you can test a function with below command:
go test -run=FuncName
You can omit -run=FuncName
part to run all the tests in the current level module. And you would benchmark a function the same function like this:
go test -bench=FuncName
Let us understand this with the help of an example. Below is main.go
with DoSomeWork
function.
|
|
The above code is trivial self-documented, needs no explanation.
Now, just like test functions follow a naming rule of TestXXX (where XXX is the function name), the benchmark also follows the same naming semantic. Here is BenchmarkDoSomeWork
in main_test.go
:
|
|
How to interpret benchmark output
When you run the benchmark suite using go test -bench=DoSome
(or go test -bench=.
for all benchmark in the current module).
You’ll see an output like:
BenchmarkDoSomeWork 535690 2337 ns/op
This means that the loop ran 4945279 times at a speed of 243 ns per loop.
Now let us optimize our DoSomeWork
by decreasing the time it’s sleeping for:
|
|
The output again:
BenchmarkDoSomeWork 1362243 890 ns/op
As you can see, our program is taking less time per operation. Earlier it was 2337 nanosecond per operation and now it’s 890.
You might have noted that the number in the second column is inversely proportional to the number is the third column, which is obvious because when the function executes in less amount of time, it will be able to run more times in a certain time frame.
Conclusion
We have learned:
- How to write benchmark tests for function.
- How to read the output of the test.
If you require further assistance then please let me know in the comments section below! And don’t forget to subscribe to the newsletter below.