
#14052: Significant GHCi speed regression with :module and `let` in GHC 8.2.1 -------------------------------------+------------------------------------- Reporter: RyanGlScott | Owner: (none) Type: bug | Status: new Priority: high | Milestone: Component: GHCi | Version: 8.2.1-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Description changed by RyanGlScott: Old description:
I recently noticed that the performance of `doctest` in GHC 8.2.1 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:
{{{#!hs -- 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:
{{{#!hs -- Foo.hs module Foo where
example :: Char example = 'a' }}}
First, use `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!
New description: I recently noticed that the performance of `doctest` in GHC 8.2.1 (see the corresponding [https://github.com/sol/doctest/issues/170 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: {{{#!hs -- 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: {{{#!hs -- Foo.hs module Foo where example :: Char example = 'a' }}} First, use `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! -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14052#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler