Go is gaining the ability to trace init calls on program startup
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.)