[Haskell-cafe] Help understanding Haskell runtime costs

Thiago Negri evohunz at gmail.com
Tue Aug 9 01:43:21 CEST 2011


Hello all,

I'm relatively new to Haskell and trying to solve some online judge's
problems in it.
One of the problems is to say if a given sentence is a tautogram or not.
A tautogram is just a sentence with all the words starting with the same letter.

My first try (solution is ok) was to do it as haskeller as possible,
trying to overcome my imperative mind.
But it did bad at performance (0.30 secs of runtime, 4.6 mb of memory):

-- code start
import Data.Char (toLower)

main = getContents >>=  mapM_ (putStrLn . toStr . isTautogram . words)
. takeWhile (/= "*") . lines

toStr :: Bool -> [Char]
toStr True = "Y"
toStr False = "N"

isTautogram :: [[Char]] -> Bool
isTautogram (x:[]) = True
isTautogram (x:xs) = all ((== firstChar) . toLower . head) xs
    where firstChar = toLower . head $ x
-- code end

I tried to profile the code, but didn't find anything useful.
My bet is that all this "words . lines" is consuming more memory than
necessary, maybe saving space for the lines already processed.
Then I tried a some-what tail-call function, consuming one line at
each iteration:

-- code start
import Data.Char (toLower)

main :: IO ()
main = getLine >>= mainLoop

mainLoop :: [Char] -> IO ()
mainLoop s | (head s) == '*' = return ()
           | otherwise       = (putStrLn . toStr . isTautogram . words
$ s) >> main

toStr :: Bool -> [Char]
toStr True = "Y"
toStr False = "N"

isTautogram :: [[Char]] -> Bool
isTautogram (x:[]) = True
isTautogram (x:xs) = all ((== firstChar) . toLower . head) xs
    where firstChar = toLower . head $ x
-- code end

Note that the only thing that changed between the two tries was the main-loop.
The second version runs faster (got 0.11 secs) and with less memory (3.6 mb)

Can someone explain to me what is really going on?
Maybe pointing out how I can achieve these optimizations using
profiling information...

Thanks,
Thiago.



More information about the Haskell-Cafe mailing list