Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would a program be faster in runghc or with profiling?

Tags:

haskell

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.

like image 887
madjar Avatar asked May 09 '15 15:05

madjar


1 Answers

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.

like image 165
madjar Avatar answered Nov 12 '22 14:11

madjar