Skip to content

GHC API is excruciatingly slow to initialize

The first use of GHC API methods runParsedDecls and compileParsedExpr can be extremely slow, I am observing numbers such as 1.5 seconds on GHC 9.4.4 and 5.8 seconds on GHC 9.6.2. The subsequent calls to these methods on the same inputs are two orders of magnitude faster, about 0.03 seconds, so it's fine in the long run, but the first call takes a while.

If you have Nix, here is a way to reproduce this: https://github.com/int-index/ghc-load-slow

$ nix shell github:int-index/ghc-load-slow -c gls-exe

Or without nix:

ghcup install ghc 9.6.2
ghcup set ghc 9.6.2
git clone https://github.com/int-index/ghc-load-slow.git
cd ghc-load-slow
CABAL_DIR="$(pwd)/platform-cabal/" cabal install --lib gls-platform
GLS_PKGDB="$(pwd)/platform-cabal/store/ghc-9.6.2/package.db" GLS_LIBDIR="$HOME/.ghcup/ghc/9.6.2/lib/ghc-9.6.2/lib/" cabal run gls-exe

Results:

First run:
Set up session: 0.002155565000
Set context: 0.031667107000
Run decls: 3.711375929000
Compile expr: 2.130753714000
ghcLoadApp: 5.876013324000

Second run:
Set up session: 0.001424016000
Set context: 0.013176788000
Run decls: 0.012871536000
Compile expr: 0.002616573000
ghcLoadApp: 0.030115064000

ghcLoadApp is the total time that it takes to set up a GHC API session and compile a few declarations and an expression. More specifically, here is the input to runParsedDecls:

data AppState0 = MkAppState1 GLS.Text GLS.Int

And here is the input to compileParsedExpr:

GLS.SomeApp
  (GLS.App
     (GLS.return
        (let
           s2 = "Hello,\nWorld"
           i3 = 8
         in MkAppState1 s2 i3))
     (\ (MkAppState1 s4 i5) ctx -> GLS.layoutText))

Naturally, I expect such a small program to be handled in a matter of milliseconds, not seconds.

Edited by Vladislav Zavialov
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information