Haskell function execution time

Haskell

Haskell Problem Overview


Is there a simple method to compute time of function execution in Haskell?

Haskell Solutions


Solution 1 - Haskell

Simplest things is to just do :set +s in ghci, and then you can see the execution time of anything you run, along with memory usage.

Solution 2 - Haskell

The criterion package was made specifically to do this well.

Solution 3 - Haskell

Solution 4 - Haskell

function execution time benchmark is included in Criterion.Measurement

for example, if I want to capture the time of someIOFunction :: IO ()

import Criterion.Measurement
main = secs <$> time_ someIOFunction >>= print

Solution 5 - Haskell

Criterion is the most sophisticated method, although I found it difficult to start, and it seems targeted to benchmarking programs. I wanted to compute the time of execution and use that data within my program and it doesn't seem to address this need, at least it's not immediately apparent.

TimeIt is very simple and does what I wanted, except it does not handle pure functions well. The time returned for a pure function is the thunk allocation time (AFAIK) and even with using seq it can be difficult to get what you want.

What is working for me is based on TimeIt.

import System.TimeIt

timeItTPure :: (a -> ()) -> a -> IO (Double,a)
timeItTPure p a = timeItT $ p a `seq` return a

In timeItTPure p a, p is the function responsible for evaluating the result of a pure calculation, a, as deeply as needed to get the good evaluation timing. Maybe this is a simple pattern match, maybe it's counting the length of a list, maybe its seq every element in the list, maybe its a deepseq, etc.

The use of seq is tricky. Note, the below function does not perform as desired. Haskell is a mysterious thing.

badTimeItTPure a = timeItT . return $ seq (p a) a

Solution 6 - Haskell

https://github.com/chrissound/FuckItTimer

start' <- start
timerc start' "begin"
print "hello"
timerc start' "after printing hello"
benchmark
timerc start' "end"
end <- getVals start'
forM_ (timert end) putStrLn

Outputs:

"hello"
begin -> after printing hello: 0.000039555s
after printing hello -> end: 1.333936928s

This seems to work fine for my very simple usecase.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question0xAXView Question on Stackoverflow
Solution 1 - HaskellRafalView Answer on Stackoverflow
Solution 2 - HaskellDaniel WagnerView Answer on Stackoverflow
Solution 3 - HaskellTylerView Answer on Stackoverflow
Solution 4 - HaskellZane XYView Answer on Stackoverflow
Solution 5 - Haskelltrevor cookView Answer on Stackoverflow
Solution 6 - HaskellChris StryczynskiView Answer on Stackoverflow