Ticket #4344: simpleFromRational.hs

File simpleFromRational.hs, 2.2 KB (added by daniel.is.fischer, 3 years ago)

Benchmark for fromRational without criterion

Line 
1{-# LANGUAGE BangPatterns #-}
2{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
3module Main (main) where
4
5import System.Environment (getArgs)
6import Data.Array.Unboxed
7import Data.Array.Base (unsafeAt)
8import System.Random
9import System.CPUTime
10import Control.Monad (when)
11import Control.Exception (evaluate)
12import Text.Printf
13import GHC.Real
14
15import Implementation
16
17test :: (Rational -> Double) -> UArray Int Int -> Int -> Double
18test conv arr len = loop len 0.0
19  where
20    rat :: Int -> Rational
21    rat k = fromIntegral n :% (fromIntegral n * fromIntegral d + 1)
22      where
23        !n = arr `unsafeAt` (2*k)
24        !d = arr `unsafeAt` (2*k+1)
25    loop 0 !acc = acc + conv (rat 0)
26    loop k  acc = loop (k-1) (acc + conv (rat k))
27
28main :: IO ()
29main = do
30    args <- getArgs
31    let size =
32          case args of
33            ("-bd":sz:_)    -> read sz
34            _               -> 200000
35    sg <- getStdGen
36    let iarr = mkIArr size sg
37        !ds = test (recip . fromRationalDouble . recip) iarr size
38    when (ds == 0) (putStrLn "Jackpot Double")
39    sequence_
40        [ bench "New fromRational :: Rational -> Double"
41            (test fromRationalDouble iarr size)
42        , bench "Old fromRational :: Rational -> Double"
43            (test fromRational iarr size)
44-- Now for Float -> Double
45        , bench "New fromRational :: Rational -> Float"
46            (fest fromRationalFloat iarr size)
47        , bench "Old fromRational :: Rational -> Float"
48            (fest fromRational iarr size)
49        ]
50
51fest :: (Rational -> Float) -> UArray Int Int -> Int -> Float
52fest conv arr len = loop len 0.0
53  where
54    rat :: Int -> Rational
55    rat k = fromIntegral n :% (fromIntegral n * fromIntegral d + 1)
56      where
57        !n = arr `unsafeAt` (2*k)
58        !d = arr `unsafeAt` (2*k+1)
59    loop 0 !acc = acc + conv (rat 0)
60    loop k  acc = loop (k-1) (acc + conv (rat k))
61
62mkIArr :: Int -> StdGen -> UArray Int Int
63mkIArr num = array (0,2*num+1) . zip [0 .. 2*num+1] . randomRs (2, maxBound-1)
64
65prec :: Double
66prec = 1e-12
67
68bench :: String -> a -> IO ()
69bench name val = do
70    t0 <- getCPUTime
71    evaluate val
72    t1 <- getCPUTime
73    printf "%s:\n    took %14.8fs\n" name (fromInteger (t1-t0)*prec)