Tuesday, September 15, 2015

Slow compilation in Golang

Because I'm lazy and Go tends to not backport it's libraries, I've decided to migrate a project from go1.4 to go1.5. Everything would be great but the compilation process of the new version is noticeably slower than the old one.

Compile all your dependencies

What I've noticed some time ago is that if you change the version of Go the libs stay at old version. This causes them to be built on each go run you invoke. And if you use a library which automates rebuilding the binary on change like reflex () than you may wait long.

List all deps

To list all dependencies your application or library have you can invoke:
go list -f '{{.Deps}}' | tr "[" " " | tr "]" " " | xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' > deps
(borrowed from from go-nuts)

Rebuild all packages

After that you can call:
go install -a $(tr -d '\n' < deps)

Update all packages

Alternative to the above, updates the code:
go install -u $(tr -d '\n' < deps)

Speedup

For my code it was from 15 seconds to below 1 second.

Apply to all subpackages in a project

As Craig Furman suggested in a comment (thanks):
go list -f '{{.Deps}}' ./... | tr "[" " " | tr "]" " " | \
  xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' | \
  xargs go install -a

3 comments:

  1. Really helpful, this brought compilation time of my project (~10 non-stdlib dependencies) down from 17 seconds back to 1 second! I now can't see a time difference between Go 1.5.1 and 1.4.2.

    ReplyDelete
    Replies
    1. Also, a modification to apply this recursively to all your sub-packages in a project:

      `go list -f '{{.Deps}}' ./... | tr "[" " " | tr "]" " " | xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' | go install -a`

      Delete
  2. thanks for this blogpost!
    http://kokizzu.blogspot.co.id/2016/06/solution-for-golang-slow-compile.html

    ReplyDelete