Ticket #4336: benchRecip.hs

File benchRecip.hs, 1.6 KB (added by daniel.is.fischer, 5 years ago)
Line 
1module Main (main) where
2
3import System.CPUTime
4import System.Environment (getArgs)
5import Text.Printf
6import GHC.Real
7import Data.Word
8import Data.Int
9
10frecip :: Integral a => Ratio a -> Ratio a
11frecip (0 :% _) = error "zero denominator"
12frecip (x :% y)
13    | x < 0     = negate y :% negate x
14    | otherwise = y :% x
15
16makeSmall :: Integral a => Ratio a -> a
17makeSmall (x :% y) = x `mod` 121 + y `mod` 97
18
19fibs :: Integral a => [a]
20fibs = 1 : 1 : go fibs (tail fibs)
21  where
22    go (x:xs) (y:ys) = x + y : go xs ys
23
24fibQuots :: Integral a => [Ratio a]
25fibQuots = go fibs
26  where
27    go (x:(xs@(y:_))) = x :% y : go xs
28
29result :: Integral a => Int -> (Ratio a -> Ratio a) -> a
30result k fun = sum . map (makeSmall . fun) $ take k fibQuots
31
32test :: Integral a => a -> Int -> IO ()
33test v k = do
34    u0 <- getCPUTime
35    print $ v + result k id
36    u1 <- getCPUTime
37    printf "id took %.6fs\n" (fromInteger (u1-u0) * (1e-12 :: Double)) :: IO ()
38    t0 <- getCPUTime
39    print $ v + result k frecip
40    t1 <- getCPUTime
41    printf "frecip took %.6fs\n" (fromInteger (t1-t0) * (1e-12 :: Double)) :: IO ()
42    t2 <- getCPUTime
43    print $ v + result k recip
44    t3 <- getCPUTime
45    printf "recip took %.6fs\n" (fromInteger (t3-t2) * (1e-12 :: Double))
46
47main :: IO ()
48main = do
49  args <- getArgs
50  let (k,t) = case args of
51                (a:b:_) -> (read a, read b)
52                (a:_)   -> (read a, 0)
53                _       -> (5000, 0)
54  case t of
55    0 -> test (0 :: Integer) k
56    1 -> test (0 :: Int) k
57    2 -> test (0 :: Int64) k
58    3 -> test (0 :: Word) k
59    4 -> test (0 :: Word64) k