pure-noise-0.2.0.0: bench/Bench.hs
import BenchLib
import Data.Typeable
import Data.Vector.Unboxed qualified as U
import Numeric.Noise
import System.Random.MWC qualified as MWC
main :: IO ()
main = do
let sz = 1_000_000
seed = 1337
octaves = 8
defaultMain
[ bgroup
"2D"
( baseline2 seed sz
<> benchPerlin2 seed octaves sz
<> benchOpenSimplex2 seed octaves sz
<> benchOpenSimplexSmooth2 seed octaves sz
<> benchValue2 seed octaves sz
<> benchValueCubic2 seed octaves sz
<> benchCombo2 seed octaves sz
<> benchCellular2 seed octaves sz
)
, bgroup
"3D"
( baseline3 seed sz
<> benchPerlin3 seed octaves sz
<> benchValue3 seed octaves sz
<> benchValueCubic3 seed octaves sz
)
]
label :: (Typeable a) => String -> Int -> Seed -> Proxy a -> String
label lbl sz seed px =
let lbl' = case lbl of
"" -> ""
v -> v <> ": "
in lbl' <> showsTypeRep (typeRep px) "" <> "[seed=" <> show seed <> "] x" <> show sz
createEnv2 :: forall a. (U.Unbox a, MWC.UniformRange a, RealFrac a) => Int -> IO (U.Vector (a, a))
createEnv2 sz = do
g <- MWC.createSystemRandom
U.generateM sz $ \i -> do
-- most of these functions zero at whole numbers and can short-circuit,
-- so a random offset should give a better signal of real world performance
offset <- MWC.uniformRM (0.00001, 0.99999) g
pure $
let r = fromIntegral $ i `div` (sz `div` 2)
c = fromIntegral $ i `mod` (sz `div` 2)
in (r + offset, c + offset)
{-# INLINE createEnv2 #-}
benchMany2
:: forall a
. (Typeable a, MWC.UniformRange a, U.Unbox a, RealFrac a)
=> String
-> Int
-> Seed
-> Noise2 a
-> Benchmark
benchMany2 lbl sz seed f =
env (createEnv2 sz) $ \ ~v ->
bench (label lbl sz seed (Proxy @(U.Vector a))) $
nf (U.map (uncurry (noise2At f seed))) v
{-# INLINE benchMany2 #-}
baseline2 :: Seed -> Int -> [Benchmark]
baseline2 seed sz =
[ bgroup
"baseline2"
[ benchMany2 @Float "" sz seed (const2 1)
, benchMany2 @Double "" sz seed (const2 2)
]
]
{-# INLINE baseline2 #-}
benchPerlin2 :: Seed -> Int -> Int -> [Benchmark]
benchPerlin2 seed octaves sz =
[ bgroup
"perlin2"
[ benchMany2 @Float "" sz seed perlin2
, benchMany2 @Double "" sz seed perlin2
, benchMany2 @Float "fractal" sz seed (fractal2 defaultFractalConfig{octaves} perlin2)
, benchMany2 @Double "fractal" sz seed (fractal2 defaultFractalConfig{octaves} perlin2)
, benchMany2 @Float "ridged" sz seed (ridged2 defaultFractalConfig{octaves} perlin2)
, benchMany2 @Double "ridged" sz seed (ridged2 defaultFractalConfig{octaves} perlin2)
, benchMany2 @Float "billow" sz seed (billow2 defaultFractalConfig{octaves} perlin2)
, benchMany2 @Double "billow" sz seed (billow2 defaultFractalConfig{octaves} perlin2)
, benchMany2 @Float "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength perlin2)
, benchMany2 @Double "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength perlin2)
]
]
{-# INLINE benchPerlin2 #-}
benchOpenSimplex2 :: Seed -> Int -> Int -> [Benchmark]
benchOpenSimplex2 seed octaves sz =
[ bgroup
"openSimplex2"
[ benchMany2 @Float "" sz seed openSimplex2
, benchMany2 @Double "" sz seed openSimplex2
, benchMany2 @Float "fractal" sz seed (fractal2 defaultFractalConfig{octaves} openSimplex2)
, benchMany2 @Double "fractal" sz seed (fractal2 defaultFractalConfig{octaves} openSimplex2)
, benchMany2 @Float "ridged" sz seed (ridged2 defaultFractalConfig{octaves} openSimplex2)
, benchMany2 @Double "ridged" sz seed (ridged2 defaultFractalConfig{octaves} openSimplex2)
, benchMany2 @Float "billow" sz seed (billow2 defaultFractalConfig{octaves} openSimplex2)
, benchMany2 @Double "billow" sz seed (billow2 defaultFractalConfig{octaves} openSimplex2)
, benchMany2 @Float "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength openSimplex2)
, benchMany2 @Double "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength openSimplex2)
]
]
{-# INLINE benchOpenSimplex2 #-}
benchOpenSimplexSmooth2 :: Seed -> Int -> Int -> [Benchmark]
benchOpenSimplexSmooth2 seed octaves sz =
[ bgroup
"superSimplex2"
[ benchMany2 @Float "" sz seed superSimplex2
, benchMany2 @Double "" sz seed superSimplex2
, benchMany2 @Float "fractal" sz seed (fractal2 defaultFractalConfig{octaves} superSimplex2)
, benchMany2 @Double "fractal" sz seed (fractal2 defaultFractalConfig{octaves} superSimplex2)
, benchMany2 @Float "ridged" sz seed (ridged2 defaultFractalConfig{octaves} superSimplex2)
, benchMany2 @Double "ridged" sz seed (ridged2 defaultFractalConfig{octaves} superSimplex2)
, benchMany2 @Float "billow" sz seed (billow2 defaultFractalConfig{octaves} superSimplex2)
, benchMany2 @Double "billow" sz seed (billow2 defaultFractalConfig{octaves} superSimplex2)
, benchMany2 @Float "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength superSimplex2)
, benchMany2 @Double "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength superSimplex2)
]
]
{-# INLINE benchOpenSimplexSmooth2 #-}
benchValue2 :: Seed -> Int -> Int -> [Benchmark]
benchValue2 seed octaves sz =
[ bgroup
"value2"
[ benchMany2 @Float "" sz seed value2
, benchMany2 @Double "" sz seed value2
, benchMany2 @Float "fractal" sz seed (fractal2 defaultFractalConfig{octaves} value2)
, benchMany2 @Double "fractal" sz seed (fractal2 defaultFractalConfig{octaves} value2)
, benchMany2 @Float "ridged" sz seed (ridged2 defaultFractalConfig{octaves} value2)
, benchMany2 @Double "ridged" sz seed (ridged2 defaultFractalConfig{octaves} value2)
, benchMany2 @Float "billow" sz seed (billow2 defaultFractalConfig{octaves} value2)
, benchMany2 @Double "billow" sz seed (billow2 defaultFractalConfig{octaves} value2)
, benchMany2 @Float "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength value2)
, benchMany2 @Double "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength value2)
]
]
{-# INLINE benchValue2 #-}
benchValueCubic2 :: Seed -> Int -> Int -> [Benchmark]
benchValueCubic2 seed octaves sz =
[ bgroup
"valueCubic2"
[ benchMany2 @Float "" sz seed valueCubic2
, benchMany2 @Double "" sz seed valueCubic2
, benchMany2 @Float "fractal" sz seed (fractal2 defaultFractalConfig{octaves} valueCubic2)
, benchMany2 @Double "fractal" sz seed (fractal2 defaultFractalConfig{octaves} valueCubic2)
, benchMany2 @Float "ridged" sz seed (ridged2 defaultFractalConfig{octaves} valueCubic2)
, benchMany2 @Double "ridged" sz seed (ridged2 defaultFractalConfig{octaves} valueCubic2)
, benchMany2 @Float "billow" sz seed (billow2 defaultFractalConfig{octaves} valueCubic2)
, benchMany2 @Double "billow" sz seed (billow2 defaultFractalConfig{octaves} valueCubic2)
, benchMany2 @Float "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength valueCubic2)
, benchMany2 @Double "pingPong" sz seed (pingPong2 defaultFractalConfig{octaves} defaultPingPongStrength valueCubic2)
]
]
{-# INLINE benchValueCubic2 #-}
benchCombo2 :: Seed -> Int -> Int -> [Benchmark]
benchCombo2 seed octaves sz =
[ bgroup
"numeric combination"
[ benchMany2 @Float "perlin * opensimplex/2" sz seed $
openSimplex2 / 2 * perlin2
, benchMany2 @Float "(4 * perlin) / 4" sz seed $
4 * perlin2 / 4
, benchMany2 @Float "(perlin + perlin + perlin + perlin) / 4" sz seed $
(perlin2 + perlin2 + perlin2 + perlin2) / 4
, benchMany2 @Float "fractal (perlin * opensimplex/2)" sz seed $
fractal2 defaultFractalConfig{octaves} (openSimplex2 / 2 * perlin2)
, benchMany2 @Float "fractal perlin * fractal opensimplex" sz seed $
fractal2 defaultFractalConfig{octaves} perlin2
* fractal2 defaultFractalConfig{octaves} openSimplex2
]
]
{-# INLINE benchCombo2 #-}
benchCellular2 :: Seed -> Int -> Int -> [Benchmark]
benchCellular2 seed _ sz =
[ bgroup
"cellular2"
( benches @Float Proxy
<> benches @Double Proxy
)
]
where
benches
:: forall a. (Typeable a, MWC.UniformRange a, U.Unbox a, RealFrac a, Floating a) => Proxy a -> [Benchmark]
benches _ =
[ benchMany2 @a (show d <> " " <> show r) sz seed (cellular2 config)
| d <- [DistEuclidean]
, r <- [CellValue, Distance2Add]
, let config = defaultCellularConfig{cellularDistanceFn = d, cellularResult = r}
]
{-# INLINE benches #-}
{-# INLINE benchCellular2 #-}
createEnv3 :: forall a m. (Monad m, U.Unbox a, Num a) => Int -> m (U.Vector (a, a, a))
createEnv3 sz = do
!ixs <- U.generateM sz $ \i ->
pure $
let d = sz `div` 3
!x = fromIntegral $ i `div` d `mod` d
!y = fromIntegral $ i `div` (d * d)
!z = fromIntegral $ i `div` d
in (x, y, z)
pure ixs
{-# INLINE createEnv3 #-}
benchMany3
:: forall a
. (Typeable a, RealFrac a, U.Unbox a)
=> String
-> Int
-> Seed
-> Noise3 a
-> Benchmark
benchMany3 lbl sz seed f =
env (createEnv3 sz) $ \ ~v ->
bench (label lbl sz seed (Proxy @(U.Vector a))) $
nf (U.map (\(x, y, z) -> noise3At f seed x y z)) v
{-# INLINE benchMany3 #-}
baseline3 :: Seed -> Int -> [Benchmark]
baseline3 seed sz =
[ bgroup
"baseline3"
[ benchMany3 @Float "" sz seed (const3 1)
, benchMany3 @Double "" sz seed (const3 2)
]
]
{-# INLINE baseline3 #-}
benchPerlin3 :: Seed -> Int -> Int -> [Benchmark]
benchPerlin3 seed octaves sz =
[ bgroup
"perlin3"
[ benchMany3 @Float "" sz seed perlin3
, benchMany3 @Double "" sz seed perlin3
, benchMany3 @Float "fractal" sz seed (fractal3 defaultFractalConfig{octaves} perlin3)
, benchMany3 @Double "fractal" sz seed (fractal3 defaultFractalConfig{octaves} perlin3)
, benchMany3 @Float "ridged" sz seed (ridged3 defaultFractalConfig{octaves} perlin3)
, benchMany3 @Double "ridged" sz seed (ridged3 defaultFractalConfig{octaves} perlin3)
, benchMany3 @Float "billow" sz seed (billow3 defaultFractalConfig{octaves} perlin3)
, benchMany3 @Double "billow" sz seed (billow3 defaultFractalConfig{octaves} perlin3)
, benchMany3 @Float "pingPong" sz seed (pingPong3 defaultFractalConfig{octaves} defaultPingPongStrength perlin3)
, benchMany3 @Double "pingPong" sz seed (pingPong3 defaultFractalConfig{octaves} defaultPingPongStrength perlin3)
]
]
{-# INLINE benchPerlin3 #-}
benchValue3 :: Seed -> Int -> Int -> [Benchmark]
benchValue3 seed octaves sz =
[ bgroup
"value3"
[ benchMany3 @Float "" sz seed value3
, benchMany3 @Double "" sz seed value3
, benchMany3 @Float "fractal" sz seed (fractal3 defaultFractalConfig{octaves} value3)
, benchMany3 @Double "fractal" sz seed (fractal3 defaultFractalConfig{octaves} value3)
, benchMany3 @Float "ridged" sz seed (ridged3 defaultFractalConfig{octaves} value3)
, benchMany3 @Double "ridged" sz seed (ridged3 defaultFractalConfig{octaves} value3)
, benchMany3 @Float "billow" sz seed (billow3 defaultFractalConfig{octaves} value3)
, benchMany3 @Double "billow" sz seed (billow3 defaultFractalConfig{octaves} value3)
, benchMany3 @Float "pingPong" sz seed (pingPong3 defaultFractalConfig{octaves} defaultPingPongStrength value3)
, benchMany3 @Double "pingPong" sz seed (pingPong3 defaultFractalConfig{octaves} defaultPingPongStrength value3)
]
]
{-# INLINE benchValue3 #-}
benchValueCubic3 :: Seed -> Int -> Int -> [Benchmark]
benchValueCubic3 seed octaves sz =
[ bgroup
"valueCubic3"
[ benchMany3 @Float "" sz seed valueCubic3
, benchMany3 @Double "" sz seed valueCubic3
, benchMany3 @Float "fractal" sz seed (fractal3 defaultFractalConfig{octaves} valueCubic3)
, benchMany3 @Double "fractal" sz seed (fractal3 defaultFractalConfig{octaves} valueCubic3)
, benchMany3 @Float "ridged" sz seed (ridged3 defaultFractalConfig{octaves} valueCubic3)
, benchMany3 @Double "ridged" sz seed (ridged3 defaultFractalConfig{octaves} valueCubic3)
, benchMany3 @Float "billow" sz seed (billow3 defaultFractalConfig{octaves} valueCubic3)
, benchMany3 @Double "billow" sz seed (billow3 defaultFractalConfig{octaves} valueCubic3)
, benchMany3 @Float "pingPong" sz seed (pingPong3 defaultFractalConfig{octaves} defaultPingPongStrength valueCubic3)
, benchMany3 @Double "pingPong" sz seed (pingPong3 defaultFractalConfig{octaves} defaultPingPongStrength valueCubic3)
]
]
{-# INLINE benchValueCubic3 #-}