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