Go packages can have
init()
initialization functions, which are called when a Go program starts as part of package initialization . One of the practical issues with
init
functions in Go so far is that their performance and even their existence is relatively opaque, so that it's hard to tell how much of an impact they have on the startup time of your programs.
The good news is that the Go team is moving to change this lack of visibility, as tracked through this issue and recently landed in the development version of Go (what will become Go 1.16) in this change . To quote the change:
runtime: implement GODEBUG=inittrace=1 support
Setting inittrace=1 causes the runtime to emit a single line to standard error for each package with init work, summarizing the execution time and memory allocation.
The emitted debug information for init functions can be used to find bottlenecks or regressions in Go startup performance.
Somewhat to my surprise, this starts acting early enough that it reports on the
init
functions even in the
runtime
package. For me, the consistent first two lines for program startup, present even with a program that does nothing, are:
init internal/bytealg @0 ms, 0 ms clock, 0 bytes, 0 allocs init runtime @0.062 ms, 0.069 ms clock, 0 bytes, 0 allocs
On the one hand, I think that making
init
functions more visible is a good thing in general, and will definitely encourage people to make them minimal. On the other hand, I wonder if people seeing a long list of
init
functions, even in typical programs, will lead to discouraging their use entirely even if the replacement isn't as good (for instance, doing the same work with
sync.Once
). It's certainly a bit startling to see how many
init
functions there are in typical Go programs.
(One rule of thumb is that you get what you measure, and reporting
init
functions is now implicitly measuring them.)