Compile time increases related to changes between `text-1.2.5.0` and `text-2.0.1`
The compile time for texmath-0.12.5.2 with GHC 9.2.4 roughly doubles from 68s to 141s when I use text-2.0.1 vs. text-1.2.5.0. A module that is particularly affected is Text.TeXMath.Readers.MathML.EntityMap which has a lot of overloaded Text literals. For this module GHC reports a large increase of the Core size with -dshow-passes:
With text-1.2.5.0:
Result size of CorePrep
= {terms: 35,732, types: 33,586, coercions: 0, joins: 0/7}
With text-2.0.1:
Result size of CorePrep
= {terms: 515,697,
types: 277,992,
coercions: 0,
joins: 4,163/4,182}
(CCing the texmath maintainer, @jgm, and @mpickering who is both an author of texmath and knows a lot about GHC performance)
I think the emojis package might have the same issue.
I think the
emojispackage might have the same issue.
Indeed. On my machine the compile time increased from 12s to 90s for emojis-0.1.2.
It seems that the overloaded literals are defined in a streaming fashion like this:
instance IsString Text where
fromString = pack
pack :: String -> Text
pack = unstream . S.map safe . S.streamList
I wonder if something like this might fare better:
instance IsString Text where
{-# INLINE fromString #-}
fromString = textFromLit
-- Prevent it from inlining right away so rules can match.
{-# INLINEABLE[2] textFromLit #-}
textFromLit :: String -> Text
textFromLit s = T.pack s
{-# RULES
"fromCLit" forall s. textFromLit (E.unpackCString# s) = T.unpackCString #s
#-}
Which would compile to the final version very quickly.
Of course this doesn't cover lazy Text and utf8 containing literals which need their own rules I suppose. But if there is no intention of supporting streaming over literals this seems like the right approach.
I guess the best solution for emojis and texmath is to pass -O0, they are unlikely to gain anything from -O1. Even better option would be to evaluate emojis in compile-time using TH (which implies -O0) and then Lift back.
For texmath I suspect -O1 makes an appreciable difference to the performance of the parsers. I guess what you mean is that we could put {-# OPTIONS_GHC -O0 #-} on just the modules that contain lots of string literals? I'd be fine with that, but it seems odd to have to resort to such a workaround. I would hope that text could eventually be changed so that this isn't needed.
I would be careful enabling -O0 just for specific modules as it will affect how other modules are optimised due to #20056