[Haskell-cafe] Timing pure functions?

Magnus Therning magnus at therning.org
Wed May 27 04:51:19 EDT 2009

Yesterday I spent about 5 minutes trying to time a single function in
haskell (after having spent about 30 minutes on the timeit module in
Python).  I found timeit[1] on Hackage but it only times an IO
computation once, what I'd like to do is time a pure function several
times.  Timing it once was no problem, passing `return $! myPureFunc`
to `timeIt` did that[2].  My feeble attempt at collecting several
timings failed though.

  import System.CPUTime
  import qualified Codec.Binary.Base64 as B64
  import System.IO
  import qualified Data.ByteString as BS
  import Control.Monad

  timeIt times ioa = let
          timeOnce = do
              t1 <- getCPUTime
              a <- ioa
              t2 <- getCPUTime
              let t = fromIntegral (t2-t1) * 1e-12
              return t
          in sequence $ take times $ repeat timeOnce

  main = do
      fh <- openBinaryFile "/dev/urandom" ReadMode
      d <- liftM BS.unpack $ BS.hGet fh 100000
      t <- timeIt 10 $ return $! B64.encode d
      print t

Running this on my machine produces the output
[2.3331e-2,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0].  I.e. the first time
the data is encoded, but the following 9 times it's not.

I suspect that it all comes from `B64.encode d` being pure, hence the
encoding happens only once.  Now I _really_ want the encoding to
happen 10 times, is there some easy way to achieve this?


[1]: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/timeit
Magnus Therning                        (OpenPGP: 0xAB4DFBA4)
magnus@therning.org          Jabber: magnus@therning.org
http://therning.org/magnus         identi.ca|twitter: magthe

More information about the Haskell-Cafe mailing list