I have a memory consumption problem when using TemplateHaskell in RuzzSolver, one of my Haskell project. Sources of RuzzSolver are available on GitHub .
To achieve good performance, I load a ~380000 words dictionary into a Tree
structure (from the containers package). This greatly speeds up the solving of grids but the loading itself takes some time (between 1 and 2 seconds depending on the CPU).
I would like to create the structure directly during compile-time with TemplateHaskell.
Therefore I transformed the dictionary loading:
-- Dictionary.hs, line 155
getDictionary :: String -> IO Dictionary
getDictionary dictionaryFilePath = do
content <- readFile dictionaryFilePath
return $ foldl (+++) [] (createTree <$> lines content)
into this function:
-- Dictionary.hs, line 164
getDictionaryQ :: String -> Q Exp
getDictionaryQ dictionaryFilePath = do
content <- runIO $ readFile dictionaryFilePath
lift $ foldl (+++) [] (createTree <$> lines content)
It allowed me to go from:
-- ruzzSolver.hs, line 68
dictionary <- getDictionary "dictionary/ruzzdictionary.txt"
to:
-- ruzzSolver.hs, line 68
let dictionary = $(getDictionaryQ "dictionary/ruzzdictionary.txt")
It (should) works but it requires too much memory to compile! On my 8 Gb PC, I had to stop GHC when it reached consumption of 12 GB. Reducing the dictionary to 38000 words lets it compile but it still needs 3 to 4 GB.
Is there a way to make GHC use less memory when compiling this TemplateHaskell code? Or another way to embed this structure into the executable?