ac-library-hs-1.4.0.0: benchmarks/Bench/Montgomery64.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE MagicHash #-}
module Bench.Montgomery64 (benches) where
import BenchLib.Montgomery64.Inline qualified as M64A
import BenchLib.Montgomery64.Noinline qualified as M64B
import Criterion
import Data.Vector.Unboxed qualified as VU
import GHC.Exts (proxy#)
import System.Random
benches :: Benchmark
benches =
bgroup
"Montgomery64"
[ -- The following four are actually meaningless:
bench "new @998244353 inline" $ whnf (VU.foldl' (\ !_ !_ -> M64A.new (proxy# @998244353)) mA) randomVec,
bench "new @998244353 noinline" $ whnf (VU.foldl' (\ !_ !_ -> M64B.new (proxy# @998244353)) mB) randomVec,
bench "new @2305843009213693951 inline" $ whnf (VU.foldl' (\ !_ !_ -> M64A.new (proxy# @2305843009213693951)) mA) randomVec,
bench "new @2305843009213693951 noinline" $ whnf (VU.foldl' (\ !_ !_ -> M64B.new (proxy# @2305843009213693951)) mB) randomVec,
-- These are the important tests:
bench "fromVal 998244353 inline" $ whnf (VU.foldl' (\ !_ !x -> M64A.fromVal (fromIntegral x)) mA) repVec1,
bench "fromVal 998244353 noinline" $ whnf (VU.foldl' (\ !_ !x -> M64B.fromVal (fromIntegral x)) mB) repVec1,
bench "fromVal 2305843009213693951 inline" $ whnf (VU.foldl' (\ !_ !x -> M64A.fromVal (fromIntegral x)) mA) repVec2,
bench "fromVal 2305843009213693951 noinline" $ whnf (VU.foldl' (\ !_ !x -> M64B.fromVal (fromIntegral x)) mB) repVec2,
bench "fromVal random inline" $ whnf (VU.foldl' (\ !_ !x -> M64A.fromVal (fromIntegral x)) mA) randomVec,
bench "fromVal random noinline" $ whnf (VU.foldl' (\ !_ !x -> M64B.fromVal (fromIntegral x)) mB) randomVec
]
where
n = 10000
mA = M64A.fromVal 3
mB = M64B.fromVal 3
randomVec :: VU.Vector Int
randomVec =
VU.map fromIntegral $
VU.unfoldrExactN n ((\(!x, !gen) -> (1 + 2 * x, gen)) <$> genWord64R (2 ^ 62 `div` 2)) (mkStdGen 123456789)
repVec1 :: VU.Vector Int
repVec1 = VU.replicate n 998244353
repVec2 :: VU.Vector Int
repVec2 = VU.replicate n 2305843009213693951