Sometimes you are facing the problem that your program just performs poorly and is very slow. It might be that is is slow during tests or in production.
It is very easy to do profiling in go. This blog post explains a lot: Profiling Go Programs
Profiling can be done with the
pprof tool of the
go command. But the most interesting part about profiling, at least for me, is, that you can also profile your test suite!. Because you can also compile the test suite into a running program. I don’t know why this command line option is not documented when calling
go test --help but it exists and works.
So, befor we start, we have to compile our test suite with:
go test -c. This gives us a binary that executes the tests.
The next step is to generate the cpu profile and use the pprof tool with it:
<ourProgram>.test -test.cpuprofile=cpu.prof go tool pprof <outProgram>.test cpu.prof Welcome to pprof! For help, type 'help'. (pprof) top10 Total: 1256 samples 1074 85.5% 85.5% 1074 85.5% code.google.com/p/go.crypto/blowfish.encryptBlock 90 7.2% 92.7% 90 7.2% runtime.usleep 45 3.6% 96.3% 45 3.6% ExternalCode ...
In our example we quickly see that an encryption method is called very often! So the problem was, that a lot of new users were generated in the integration test suite and the passwords were hashed every time with bcrypt. A quick refactoring (make the password hashing replacable via an interface) helped to reduce the time to execute the tests significantly.
Mac OS X
Be aware if you are running on MAC OS X. The pprof tool will not work there and just outputs wait time on some mutex which isn’t helpful at all. As far as I know this is because the pprof tool is incompatible with the kernel. You can patch the kernel by using this Mac Fix Github Project here, but this is risky, so I wouldn’t do it and suggest to just run a Linux VM for profiling :P