F# Compiler Server: results

Compiler repos/server @ 2df01fc34c, built solution: dotnet/fsharp main @ 99406265c8. Recorded 2026-10-18T09:48:01+0100. Plan: plan.html. Code: compiler_server (diff). Later, more complete results: report.

Whole build of FSharp.Compiler.Service.slnx, mean of the measured runs: compiler server 48.8 s vs stock 66.1 s (1.35×) and vs stock + JIT flags 45.9 s (0.94×).

Findings

Correctness

Performance (whole build, 11-core M-series)

Next experiments

Wall time per build

0s10s20s30s40s50s60s70s80sbaseline (stock fsc) · warmup73.0 sbaseline (stock fsc) · run166.9 sbaseline (stock fsc) · run265.3 sbaseline + JIT flags · warmup46.0 sbaseline + JIT flags · run145.7 sbaseline + JIT flags · run246.1 scompiler server · warmup68.7 scompiler server · run155.2 scompiler server · run242.5 scompiler server, longer sequence · warmup78.5 scompiler server, longer sequence · run143.4 scompiler server, longer sequence · run246.3 scompiler server, longer sequence · run353.0 scompiler server, longer sequence · run445.3 scompiler server, longer sequence · run537.9 s
Faded bars are the warm-up builds. For the server, the warm-up build is the cold start: it starts the workers, which then JIT the compiler. Each config ran 1 warm-up and 2 measured builds, sequentially, with MSBuild node reuse off. The longer server sequence (1 warm-up and 5 measured builds) is an extra run, beyond the requested protocol.

Speedup (measured runs)

Configwall sCPU sspeedup vs stockΔ wall vs stock speedup vs stock + flagsΔ CPU vs stock
baseline (stock fsc)66.1491.01.00×0.0%0.69×0.0%
baseline + JIT flags45.9341.91.44×-30.6%1.00×-30.4%
compiler server48.8263.71.35×-26.1%0.94×-46.3%
compiler server, longer sequence45.2267.51.46×-31.7%1.02×-45.5%

Every build

Outputs: the assembly (with its embedded PDB), the reference assembly and the XML doc of all 17 compilations, 48 files, compared by SHA-256. Stock builds are not deterministic for 2 of them (net11.0/refint/FSharp.Compiler.Service.dll, net10.0/refint/FSharp.Core.dll), so a build passes when every file matches a hash some stock build produced. Diagnostics: the distinct warning/error FS lines of the build log.

ConfigBuildwall sCPU sworker CPU sworkers alive workers startedworker RSS MBidentical to 1st stock buildoutputs no stock build produceddiagnostics
baseline (stock fsc)warmup73.0479.50.000048/48nonesame
baseline (stock fsc)run166.9493.90.000047/48none
other stock variant: FSharp.Compiler.Service.dll
same
baseline (stock fsc)run265.3488.10.000047/48none
other stock variant: FSharp.Compiler.Service.dll
same
baseline + JIT flagswarmup46.0342.20.000046/48none
other stock variant: FSharp.Compiler.Service.dll, FSharp.Core.dll
same
baseline + JIT flagsrun145.7341.40.000047/48none
other stock variant: FSharp.Compiler.Service.dll
same
baseline + JIT flagsrun246.1342.40.000047/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler serverwarmup68.7478.3415.699401548/48nonesame
compiler serverrun155.2289.2230.190425947/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler serverrun242.5238.2186.490403047/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler server, longer sequencewarmup78.5383.1326.899582547/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler server, longer sequencerun143.4260.1201.290399147/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler server, longer sequencerun246.3305.9240.990457947/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler server, longer sequencerun353.0272.1211.290345847/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler server, longer sequencerun445.3258.9197.890413547/48none
other stock variant: FSharp.Compiler.Service.dll
same
compiler server, longer sequencerun537.9240.6178.390357648/48nonesame

Who compiled what

From the build logs (binlog replay): compilations served by a worker, compilations that fell back to a stock process, and how the 17 compilations spread over workers.

Buildby a workerstock fallbackper worker
server warmup1705 · 4 · 2 · 1 · 1 · 1 · 1 · 1 · 1
server run11706 · 5 · 2 · 2 · 1 · 1
server run21706 · 5 · 3 · 1 · 1 · 1
server_long warmup1707 · 3 · 1 · 1 · 1 · 1 · 1 · 1 · 1
server_long run11707 · 5 · 3 · 1 · 1
server_long run21705 · 5 · 2 · 1 · 1 · 1 · 1 · 1
server_long run31706 · 4 · 2 · 2 · 1 · 1 · 1
server_long run41706 · 5 · 2 · 2 · 1 · 1
server_long run51707 · 5 · 2 · 1 · 1 · 1

Method