Skip to content

Instantly share code, notes, and snippets.

@jjclxrk
Last active October 15, 2020 10:02
Show Gist options
  • Select an option

  • Save jjclxrk/645a6e1601a431c25f151f41fb23c104 to your computer and use it in GitHub Desktop.

Select an option

Save jjclxrk/645a6e1601a431c25f151f41fb23c104 to your computer and use it in GitHub Desktop.
import Data.Time
import Data.Time.Clock.System
-- Function that potentially does a lot of unnecessary work in order to chew
-- up time.
f :: Integer -> Integer
f x = if x <= 0 then 0 else f (pred x)
-- The first guard condition will fail, and we are interested in the timing
-- to see if `f a` is computed again.
myfunc0 :: Integer -> Integer -> Integer
myfunc0 a b
| f a + f b > 0 = 1
| f a == 0 = 2
| otherwise = 3
myfunc1 :: Integer -> Integer -> Integer
myfunc1 a b
| resulta + resultb > 0 = 1
| resulta == 0 = 2
| otherwise = 3
where
resulta = f a
resultb = f b
-- Does `myfunc3` take twice as long to compute as `myfunc2`?
myfunc2 :: Integer -> t -> Integer
myfunc2 a _ = f a
myfunc3 :: Integer -> t -> Integer
myfunc3 a _ = f a + f a
-- The type of the function that the benchmark function is expecting is
-- fairly arbitrary, but it was chosen to match the example from Canvas
bench :: (Show b) => String -> (a -> a -> b) -> (a, a) -> IO ()
bench name f (x,y) = do
t0 <- getSystemTime
-- We have to do something with the result, otherwise Haskell's lazy
-- evaluation means we will never evaluate the function.
-- So, we print it.
putStrLn name >> print (uncurry f (x,y))
t1 <- getSystemTime
print $ diffUTCTime (systemToUTCTime t1) (systemToUTCTime t0)
-- Number to count down from.
startFrom :: Integer
startFrom = 9999999
main = do
bench "myfunc0 -- no where clause" myfunc0 (startFrom, 1)
bench "myfunc1 -- where clause" myfunc1 (startFrom, 1)
bench "myfunc2 -- f a" myfunc2 (startFrom, 1)
bench "myfunc3 -- f a + f a" myfunc3 (startFrom, 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment