I've got the following program that takes a big input (a list of extension/mime mapping, a list of files) and output results line by line (the mime type for each file).
import System.IO
import Control.Monad
import qualified Data.Map as M
import System.FilePath
import Data.Char
main :: IO ()
main = do
input_line <- getLine
let n = read input_line :: Int -- Number of elements which make up the association table.
input_line <- getLine
let q = read input_line :: Int -- Number Q of file names to be analyzed.
mimeMap <- fmap M.fromList $ replicateM n $ do
input_line <- getLine
let input = words input_line
let ext = input!!0 -- file extension
let mt = input!!1 -- MIME type.
return (map toLower ext, mt)
replicateM_ q $ do
fname <- getLine
let ext = map toLower . drop 1 . takeExtension $ fname
mime = M.findWithDefault "UNKNOWN" ext mimeMap
putStrLn mime
The program was quite slow, so I started profiling it, and I got a strange result.
When compiled with
ghc --make -O2 coding.hs
the program is very slow. However, the -fprof-auto
seems to speed it all up. Compiled with
ghc --make -O2 coding.hs -prof -fprof-auto -fforce-recomp
makes it blazing fast -prof
alone has no effect.
Strangely, it is also very fast when run with runghc coding.hs
.
I have no idea in what direction to go from there. Does anyone understand what is happenning here?
EDIT: I should mention that my ghc is 7.10.1.
To provide a complete answer to the question:
As Reid Barton mentioned, the problem seems to be the infamous state hack optimization, which inlines mimeMap
into the repeated IO action, executing it much more times than necessary. -fno-state-hack
disables that optimization and solves the problem. Another way to solve the problem is to force a strict evaluation of ``mimeMap.
!mimeMap <- fmap M.fromList $ replicateM n [...]
However, there also seems to be a regression in GHC 7.10, in which -fno-state-hack
does not solves the problem. That explains why it didn't fix it for me.
Thanks a lot everyone for your answers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With