7.8.1 uses a lot of memory when compiling attoparsec programs using <|>
To reproduce, install a pre-0.11.2.1 version of attoparsec. This bug was worked around in 0.11.2.1 by removing the INLINE on plus in attoparsec.
With this test program:
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import Data.Attoparsec.Text
import Data.Text (Text)
parser :: Parser Text
parser = string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
<|> string "a" <|> string "a"
main :: IO ()
main = parseTest parser "a"
and using GHC 7.8.1.rc2:
Compiling using -O2, GHC tops out at ~1GB of RAM and takes 25s.
Using -O0, GHC takes 0.47s and uses <150MB of RAM.
Compare this with GHC 7.6.3:
Compiling using -O2, GHC uses <150MB and takes 3.7s. Memory usage is similar with -O0 although compile time goes down to 0.36s.
An extreme version of this bug can be found in the thyme package here: https://github.com/liyang/thyme/blob/master/src/Data/Thyme/Format.hs#L589-L693. Compiling that module with an unfixed attoparsec makes GHC use all available memory and stall out, forcing kill -9. Replacing the function body with undefined makes the package compile as expected.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 7.8.1-rc2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |