[GHC] #14052: Significant GHCi speed regression with :module and `let` in GHC 8.2.1

GHC ghc-devs at haskell.org
Sat Jul 29 06:29:06 UTC 2017


#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
           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:
-------------------------------------+-------------------------------------
 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!

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14052>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list