Significant GHCi speed regression with :module and `let` in GHC 8.2.1
I recently noticed that the performance of
doctest in GHC 8.2.1 (see the corresponding doctest issue) can be much, much worse than in previous versions of 8.0.2. So bad, in fact, that a project with 865
doctest examples takes about three hours to complete in 8.2.1, whereas it would only take 8 seconds in 8.0.2.
To reproduce this issue in a fairly minimal way, you can use the following script to generate a file which simulates what
doctest is doing:
-- GenExample.hs module Main where import Control.Monad import System.Environment import System.Exit import System.IO main :: IO () main = do args <- getArgs case args of n:_ -> genExamples (read n) _ -> do hPutStrLn stderr "usage: runghc GenExamples.hs <num-examples>" exitWith $ ExitFailure 1 genExamples :: Int -> IO () genExamples nExamples = do putStrLn ":l Foo" ireplicateA_ nExamples genExample genExample :: Int -> IO () genExample i = putStr $ unlines [ ":m *Foo" , "example : \"expr" ++ show i ++ "\"" , "let foo = it" , "\"marker\"" , "let it = foo" ] ireplicateA_ :: Applicative m => Int -> (Int -> m a) -> m () ireplicateA_ cnt0 f = loop cnt0 0 where loop cnt n | cnt <= 0 = pure () | otherwise = f n *> (loop (cnt - 1) $! (n + 1))
You'll also need this file:
-- Foo.hs module Foo where example :: Char example = 'a'
GenExample to generate a GHCi script:
$ runghc GenExample.hs 500 > Example.script
Now you can run the script like so (using GHCi 8.0.2 as an example):
$ /opt/ghc/8.0.2/bin/ghci -ghci-script Example.script Foo.hs
With GHCi 8.0.2, this takes about three seconds. But with GHCi 8.2.1, this takes about 35 seconds!