Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,869
    • Issues 4,869
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 456
    • Merge requests 456
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #14052
Closed
Open
Created Jul 29, 2017 by Ryan Scott@RyanGlScottMaintainer

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'

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!

Edited Mar 10, 2019 by Ryan Scott
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking