Skip to content

Compile with DOTNET_TieredPGO=0 DOTNET_TC_CallCountingDelayMs=0 for faster compilation #20802

Description

@safesparrow

Is your feature request related to a problem? Please describe.

Compilation is slow.

Describe the solution you'd like

Setting DOTNET_TieredPGO=0 DOTNET_TC_CallCountingDelayMs=0 for the compiler process (fsc.dll) can significantly speed it up.

Describe alternatives you've considered

Additional context

At G-Research I have spent considerable time trying to optimise F# compilation times of our large solution (mixed C# + F#).

As part of that I discovered that the following two runtime JIT flags have a large impact on compilation times & CPU time:

  1. DOTNET_TieredPGO=0
  2. DOTNET_TC_CallCountingDelayMs=0

Internal tests at G-Research against internal projects showed large speed ups.
We have onboarded these settings in some of our environments.

Today I executed extensive AI-driven multi-hour tests at home against the compiler codebase and saw similar results.

Reports

A few AI-generated reports with varying level of detail:

Results summary - AI-generated

  • All 14 compilations of FSharp.Compiler.Service.slnx together (newest target framework of each project, parallel compilation on): 63.1 s → 36.3 s wall (−42.5%, 95% CI −43.4% to −41.9%), CPU −31.0% (−32.7% to −29.4%).
  • Medium and large compilations (6 of 14, 1.5 s to 25 s): wall −56% to −36%, CPU −43% to +2%. FSharp.Compiler.Service itself: 24.4 s → 13.5 s.
  • Small compilations (8, under 1.5 s): wall −19% to −3%, but CPU +20% to +49%: the process ends before recompiling startup code pays off.
  • Whole dotnet build of Fantomas (SDK 11, 6 runs per mode): −18.7% wall with the settings on fsc only
  • GC pause time is unchanged (−1.1%). JIT CPU time goes up (+202%), mostly on the background tier-1 thread, which is what buys the speed-up.

This vs a compilation server

Note that this is related to the F# compilation server concept that we have been working on.
For server-based compilation, the default runtime settings are adequate and changing them is likely to reduce performance - but server compilation is not yet available, and this could be a nice easy speed up until it is.

Results

The two sections below describe compiling the full compiler solution with 14 projects.

Speed up per project

All large & medium projects show significant wall-clock time and CPU time reduction.
The smallest projects (that compile in ~1s) show slightly reduced wall-clock time and increased CPU time.

Image

Aggregate timings of each compilation phase

Image
All compilations, sum of medians Defaults Flags Δ (95% CI)
Wall time 63.1 s 36.3 s -42.5% (-43.4 to -41.9)
CPU time 210.0 s 144.8 s -31.0% (-32.7 to -29.4)
JIT time (all threads) 9.1 s 27.6 s +201.9% (+190.1 to +206.2)
GC pause time 6.1 s 6.1 s -1.1% (-2.0 to +0.6)
Phase: Import references 2.9 s 2.3 s -19.3% (-20.2 to -18.4)
Phase: Parse 2.2 s 2.0 s -7.2% (-8.6 to -5.2)
Phase: Typecheck 23.6 s 12.2 s -48.2% (-51.6 to -47.5)
Phase: Optimizations 18.1 s 9.5 s -47.3% (-48.2 to -45.4)
Phase: TAST -> IL 5.8 s 3.6 s -39.3% (-41.2 to -34.9)
Phase: Write .NET binary 6.1 s 3.6 s -41.9% (-42.7 to -39.5)
Phase: Other phases 2.4 s 1.4 s -44.3% (-47.0 to -42.2)
Phase: Startup & exit 1.5 s 1.5 s +0.1% (-0.8 to +1.0)

Activity

  1. added this to the Backlog milestone on Oct 17, 2026
  2. safesparrow commented on Oct 17, 2026

    @safesparrow
    ContributorAuthor

    @T-Gro I forgot to discuss these in more detail earlier this week. These are settings that in my testing significantly speed up compilation across all codebases tested, and are a middle ground between the current setup and a future F# compilation server.

    As these are completely safe in terms of compilation outputs (determinism etc), it should be easier to get these in.

    I will raise an issue for the compilation server separately.

  3. baronfel commented on Oct 17, 2026

    @baronfel
    Member

    @safesparrow when you say that applying these flags to MSBuild also resulted in wall clock improvements, was that with or without MSBuild Multithreaded Mode (-mt) in use? I'm very curious about mor general build performance improvements too, but with the MSBuild Server (which MT uses) I would expect the tiered compilation to benefit us over time.

  4. safesparrow commented on Oct 17, 2026

    @safesparrow
    ContributorAuthor

    @safesparrow when you say that applying these flags to MSBuild also resulted in wall clock improvements, was that with or without MSBuild Multithreaded Mode (-mt) in use?

    @baronfel Sorry, that was without node reuse, so without the server either - better stability run-to-run, but not actually relevant for judging MSBuild changes.

    Please discard that point about MSBuild speed ups. As with the compiler server, long-running processes like MSBuild worker nodes/server should work best with the default settings.

  5. T-Gro commented on Oct 21, 2026

    @T-Gro
    Member

    I see the JIT time went up -> I will test if just disabling QuickJit will bring similar result.
    So that precompiled code could still participate when its available (e.g. the BCL).

  6. safesparrow commented on Oct 22, 2026

    @safesparrow
    ContributorAuthor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions