Skip to content

cmd/compile: slow compilation of packages with many global initializers #77153

@podtserkovskiy

Description

@podtserkovskiy

Problem

Packages with many global variables requiring runtime initialization compile slowly because the compiler generates a single monolithic init function containing all initialization statements.

This pattern doesn't typically occur in handwritten code, but can happen in generated code (e.g., Thrift).

Large functions are expensive to compile, especially during SSA optimization passes. For comparison, compiling a package with 500,000 items:

Package contents Compile time
Static variables 5 seconds
Functions 23 seconds
Dynamic initializers ~1 minute

The dynamic initializer in this example is fmt.Sprintf("hello").

The dynamic initializers case is significantly slower because all 500,000 initialization statements end up in a single giant init function.

Full benchmark code: https://github.com/podtserkovskiy/go-dynamic-init-bench

We briefly discussed this problem at GopherCon 2025 and the consensus was that it's worth trying to optimize.

Proposed Solution

Split the synthetic init function into multiple smaller functions when the number of initialization statements exceeds N (let's say 1000). Statements are distributed into init.var.N functions (e.g., init.var.0, init.var.1, etc.) which are added to the .inittask structure for runtime execution in order.

I've tried to implement this. Here are the benchmark results:

Approach Compile time
Dynamic initializers ~1 minute
Manually split code 14 seconds
Code split in the compiler 14 seconds

The numbers are better than before but not as good as pre-generated code.

I'm going to publish a CL with the implementation shortly.

Metadata

Metadata

Assignees

Labels

FeatureRequestIssues asking for a new feature that does not need a proposal.FixPendingIssues that have a fix which has not yet been reviewed or submitted.ToolSpeedcompiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions