module Main ( main ) where import Criterion.Main import Control.DeepSeq import qualified Data.Foldable as F import Data.IntMap ( IntMap ) import qualified Data.IntMap as IM import qualified Data.List as L import Data.Sequence ( Seq ) import qualified Data.Sequence as S import Data.Vector.Persistent ( Vector ) import qualified Data.Vector.Persistent as V testListRTraversal :: [Int] -> Int testListRTraversal = L.foldr (+) 0 testListLSTraversal :: [Int] -> Int testListLSTraversal = L.foldl' (+) 0 testVecRTraversal :: Vector Int -> Int testVecRTraversal = V.foldr (+) 0 testIMRTraversal :: IntMap Int -> Int testIMRTraversal = F.foldr (+) 0 testVecLTraversal :: Vector Int -> Int testVecLTraversal = V.foldl' (+) 0 testSeqRTraversal :: Seq Int -> Int testSeqRTraversal = F.foldr (+) 0 testSeqLTraversal :: Seq Int -> Int testSeqLTraversal = F.foldl (+) 0 testVecLSTraversal :: Vector Int -> Int testVecLSTraversal = V.foldl' (+) 0 testSeqLSTraversal :: Seq Int -> Int testSeqLSTraversal = F.foldl' (+) 0 testListIndex :: [Int] -> Int -> Int testListIndex = (!!) testSeqIndex :: Seq Int -> Int -> Int testSeqIndex = S.index testVecIndex :: Vector Int -> Int -> Int testVecIndex = V.unsafeIndex testIMIndex :: IntMap Int -> Int -> Maybe Int testIMIndex = flip IM.lookup testSeqRange :: Seq Int -> Int -> Int -> Int testSeqRange s start end = sum $ map (S.index s) [start..end] testVecRange :: Vector Int -> Int -> Int -> Int testVecRange v start end = sum $ map (V.unsafeIndex v) [start..end] testIMAppend :: IntMap Int -> Int -> Int -> IntMap Int testIMAppend im ix i = IM.insert ix i im testSeqAppend :: Seq Int -> Int -> Seq Int testSeqAppend = (S.|>) testVecAppend :: Vector Int -> Int -> Vector Int testVecAppend = V.snoc testIMUpdate :: IntMap Int -> Int -> Int -> IntMap Int testIMUpdate m ix elt = IM.insert ix elt m testSeqUpdate :: Seq Int -> Int -> Int -> Seq Int testSeqUpdate s ix elt = S.update ix elt s testVecUpdate :: Vector Int -> Int -> Int -> Vector Int testVecUpdate v ix elt = V.update ix elt v testIMBuild :: Int -> IntMap Int testIMBuild len = let l = [0..len] in L.foldl' (\m (ix, elt) -> IM.insert ix elt m) IM.empty (zip l l) testSeqBuild :: Int -> Seq Int testSeqBuild len = L.foldl' (S.|>) S.empty [0..len] testVecBuild :: Int -> Vector Int testVecBuild len = L.foldl' V.snoc V.empty [0..len] main :: IO () main = setup >> defaultMain [ bgroup "traverse1000" [ bench "ListR1000" $ whnf testListRTraversal l1000 , bench "IMR1000" $ whnf testIMRTraversal im1000 , bench "SeqR1000" $ whnf testSeqRTraversal s1000 , bench "VecR1000" $ whnf testVecRTraversal v1000 , bench "SeqL1000" $ whnf testSeqLTraversal s1000 , bench "VecL1000" $ whnf testVecLTraversal v1000 , bench "ListLS1000" $ whnf testListLSTraversal l1000 , bench "SeqLS1000" $ whnf testSeqLSTraversal s1000 , bench "VecLS1000" $ whnf testVecLSTraversal v1000 ], bgroup "indexAt3_1000" [ bench "List1000" $ whnf (testListIndex l1000) 3 , bench "IM1000" $ whnf (testIMIndex im1000) 3 , bench "Seq1000" $ whnf (testSeqIndex s1000) 3 , bench "Vec1000" $ whnf (testVecIndex v1000) 3 ], bgroup "indexAt30_1000" [ bench "List1000" $ whnf (testListIndex l1000) 30 , bench "IM1000" $ whnf (testIMIndex im1000) 30 , bench "Seq1000" $ whnf (testSeqIndex s1000) 30 , bench "Vec1000" $ whnf (testVecIndex v1000) 30 ], bgroup "indexAt30_10000" [ bench "Seq10000" $ whnf (testSeqIndex s10000) 30 , bench "Vec10000" $ whnf (testVecIndex v10000) 30 ], bgroup "indexAt3000_10000" [ bench "IM1000" $ whnf (testIMIndex im10000) 3000 , bench "Seq10000" $ whnf (testSeqIndex s10000) 3000 , bench "Vec10000" $ whnf (testVecIndex v10000) 3000 ], bgroup "indexRange501-550_10000" [ bench "Seq10000" $ whnf (testSeqRange s10000 501) 550 , bench "Vec10000" $ whnf (testVecRange v10000 501) 550 ], bgroup "indexRange5001-5500_100000" [ bench "Seq10000" $ whnf (testSeqRange s100000 5001) 5500 , bench "Vec10000" $ whnf (testVecRange v100000 5001) 5500 ], bgroup "appendValue1000" [ bench "IM1000" $ whnf (testIMAppend im1000 1000) 1 , bench "Seq1000" $ whnf (testSeqAppend s1000) 1 , bench "Vec1000" $ whnf (testVecAppend v1000) 1 ], bgroup "appendValue100000" [ bench "IM100000" $ whnf (testIMAppend im100000 100000) 1 , bench "Seq100000" $ whnf (testSeqAppend s100000) 1 , bench "Vec100000" $ whnf (testVecAppend v100000) 1 ], bgroup "updateIndex5_1000" [ bench "IM1000" $ whnf (testIMUpdate im1000 5) 342 , bench "Seq1000" $ whnf (testSeqUpdate s1000 5) 342 , bench "Vec1000" $ whnf (testVecUpdate v1000 5) 342 ], bgroup "updateIndex5000_100000" [ bench "IM100000" $ whnf (testIMUpdate im100000 5000) 342 , bench "Seq100000" $ whnf (testSeqUpdate s100000 5000) 342 , bench "Vec100000" $ whnf (testVecUpdate v100000 5000) 342 ], bgroup "build1000" [ bench "IM1000" $ whnf testIMBuild 1000 , bench "Seq1000" $ whnf testSeqBuild 1000 , bench "Vec1000" $ whnf testVecBuild 1000 ] ] where setup = do l1000 `deepseq` l10000 `deepseq` l10000 `deepseq` v1000 `deepseq` v10000 `deepseq` v100000 `deepseq` im1000 `deepseq` im10000 `deepseq` im100000 `deepseq` return () S.sort s1000 `seq` S.sort s10000 `seq` S.sort s100000 `seq` return () l1000 :: [Int] l1000 = [0..1000] l10000 :: [Int] l10000 = [0..10000] l100000 :: [Int] l100000 = [0..100000] v1000 = V.fromList l1000 v10000 = V.fromList l10000 v100000 = V.fromList l100000 s1000 = S.fromList l1000 s10000 = S.fromList l10000 s100000 = S.fromList l100000 im1000 = IM.fromList (zip l1000 l1000) im10000 = IM.fromList (zip l10000 l10000) im100000 = IM.fromList (zip l100000 l100000)