Skip to content

Compilation time optimization

Compilation time is a first-class engineering concern in Saturn. Slow builds disrupt iteration, discourage experimentation, and make refactoring costly. As the codebase grows, unmanaged dependencies quickly turn incremental changes into full rebuilds.

Saturn addresses this problem by reducing header coupling, limiting transitive includes, and helping the compiler reuse work whenever possible. The strategies described here are mandatory guidelines for engine development and contributor code.


Saturn uses CMake precompiled headers to reduce repeated parsing of large, frequently used headers. CMake injects these headers automatically through compiler options. You must not include them manually in source files.

target_precompile_headers(
saturn
PRIVATE
<vector>
<string>
<iostream>
<algorithm>
<unordered_map>
<unordered_set>
<functional>
<memory>
<array>
<chrono>
)

Precompiled headers are most effective when they contain headers that are:

  • Expensive to parse
  • Widely used across translation units
  • Stable over time

Follow these rules when modifying PCH contents:

  • Include only general-purpose headers used broadly across the engine
  • Avoid project-specific headers or implementation details
  • Avoid headers that change frequently
  • Prefer STL and platform headers with high parse cost

Poorly chosen PCH contents increase rebuild times instead of reducing them.


Saturn relies on Visual Studio 2022 build analysis tools to track compilation performance on Windows. These tools are used to identify:

  • Excessive template instantiations
  • Headers included transitively across many files
  • Translation units with disproportionate compile cost

Use this data to guide refactoring. Optimization decisions must be driven by measured impact, not intuition.

When a file or header becomes a compile-time hotspot, address the dependency structure rather than adding workarounds.


Saturn selectively uses opaque handles to reduce header dependencies in large or widely used APIs. This pattern replaces concrete type exposure with forward-declared, incomplete types.

This approach is especially useful in systems such as the renderer, where exposing full type definitions would otherwise force large transitive include chains.

Opaque handles are not a free optimization.

Benefits:

  • Reduced header coupling
  • Faster incremental builds
  • Cleaner public interfaces

Costs:

  • Additional indirection
  • Reduced type visibility
  • Potential ABI safety implications if misused

Use opaque handles deliberately. Favor clarity and correctness over compile-time savings when the tradeoff is unclear.


Compilation time optimization is an ongoing effort. Planned improvements include:

  • Splitting the engine into multiple CMake targets This allows subsystem-specific dependency graphs and tailored PCH sets.

  • Subsystem-scoped PCH usage Each major subsystem will eventually define its own precompiled headers.

  • Evaluation of C++20 modules Modules are not yet production-ready across all supported toolchains. Saturn will adopt them only when support is stable and measurable benefits outweigh migration costs.


Compilation speed is a structural property of the codebase, not a post-hoc optimization. Clean boundaries, minimal headers, and explicit dependencies matter more than any individual tool or flag.

Every header you add today affects build times tomorrow.