import Criterion.Main -- vectors import qualified Data.Vector.Unboxed as V import qualified Data.Vector.Unboxed.Mutable as MV -- functors import Control.Applicative import Control.Monad (mapM_,replicateM) import Data.Foldable (sequenceA_) import Control.Monad.Trans.Class -- state import Control.Monad.Trans.State -- phantom-state import Control.Applicative.PhantomState replicateA_ :: Applicative f => Int -> f a -> f () replicateA_ n f = sequenceA_ (replicate n f) createVector1 :: Int -> V.Vector Int createVector1 n = V.create $ do v <- MV.unsafeNew n let step = StateT $ \i -> do MV.unsafeWrite v i i pure ((),i+1) execStateT (replicateA_ n step) 0 return v createVector2 :: Int -> V.Vector Int createVector2 n = V.create $ do v <- MV.unsafeNew n let step = useAndChangeState $ \i -> do MV.unsafeWrite v i i pure (i+1) runPhantomStateT (replicateA_ n step) 0 return v createVector3 :: Int -> V.Vector Int createVector3 n = V.create $ do v <- MV.unsafeNew n mapM_ (\i -> MV.unsafeWrite v i i) [0..n-1] return v createVector4 :: Int -> V.Vector Int createVector4 n = V.create $ do v <- MV.unsafeNew n let loop = do i <- get if i == n then pure () else do lift $ MV.write v i i modify (+1) loop execStateT loop 0 return v main :: IO () main = defaultMain [ bgroup "vector-create" [ bench "generate" $ whnf (\i -> V.generate i id) 10000 , bench "state" $ whnf createVector1 10000 , bench "phantom-state" $ whnf createVector2 10000 , bench "mapM_" $ whnf createVector3 10000 , bench "state-loop" $ whnf createVector4 10000 ] ]