module Main where
import Criterion.Main
import Data.PrimitiveArray as PA
go ∷ (Index i) ⇒ Int → Unboxed i Int → i → Int
{-# Inline go #-}
go !c !pa !i = f c i 0
where f 0 !i !acc = acc
f !k !i !acc = f (k-1) i (acc + pa ! i)
go1 ∷ Int → Unboxed (Z:.Int) Int → (Z:.Int) → Int
{-# NoInline go1 #-}
go1 = go
go2 ∷ Int → Unboxed (Z:.Int:.Int) Int → (Z:.Int:.Int) → Int
{-# NoInline go2 #-}
go2 = go
go3 ∷ Int → Unboxed (Z:.Int:.Int:.Int) Int → (Z:.Int:.Int:.Int) → Int
{-# NoInline go3 #-}
go3 = go
main ∷ IO ()
main = do
let !(pa1 ∷ Unboxed (Z:.Int) Int) = PA.fromAssocs (ZZ:..LtInt 10) 0 []
let !(pa2 ∷ Unboxed (Z:.Int:.Int) Int) = PA.fromAssocs (ZZ:..LtInt 10:..LtInt 10) 0 []
let !(pa3 ∷ Unboxed (Z:.Int:.Int:.Int) Int) = PA.fromAssocs (ZZ:..LtInt 10:..LtInt 10:..LtInt 10) 0 []
defaultMain
[ bgroup "1"
[ bench "10^0" $ whnf (go1 1 pa1) (Z:.5)
, bench "10^3" $ whnf (go1 1000 pa1) (Z:.5)
, bench "10^6" $ whnf (go1 1000000 pa1) (Z:.5)
, bench "10^9" $ whnf (go1 1000000000 pa1) (Z:.5)
]
, bgroup "2"
[ bench " 1" $ whnf (go2 1 pa2) (Z:.5:.5)
, bench " 1000" $ whnf (go2 1000 pa2) (Z:.5:.5)
, bench "1000000" $ whnf (go2 1000000 pa2) (Z:.5:.5)
]
, bgroup "3"
[ bench " 1" $ whnf (go3 1 pa3) (Z:.5:.5:.5)
, bench " 1000" $ whnf (go3 1000 pa3) (Z:.5:.5:.5)
, bench "1000000" $ whnf (go3 1000000 pa3) (Z:.5:.5:.5)
]
]