Skip to content

poor compile time and memory usage with OverloadedString Text concatenation

(sorry, the template list seems broken here)

The following code does exhibits abysmally poor build performance and memory usage.

{-# OPTIONS_GHC -O2 #-}
{-# LANGUAGE OverloadedStrings #-}

module DocDebug where

import           Data.Text
import Data.String

foo :: Text
foo = "foo" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar" <> "bar"

Using ghc -fforce-recomp DocDebug.hs +RTS -s, the report returns 17s and ~2700 MiB of max resident memory.

Note that -O2 is important here, that's why I put it in the file itself.

Different observations:

  • If I change the type signature from Text to String, the performances changes back to normal, i.e. 0.11s and 22 MiB. However we are building a String instead of Text.
  • If I keep the Text type, but wraps everything in a fromString (i.e. foo = fromString $ "foo" <> "bar" <> "....), 0.11s and 22 MiB too. Same semantic, but 150 times faster and 120 times less memory used.

With -O1, results are similar, but not as dramatic:

  • Initial code snipet, with -O1: 1s for 66 MiB
  • With :: String, 0.14s, 23 MiB
  • With fromString, 0.15s, 23 MiB.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information