enummapmap-0.4.0: bench/IntMapVsEnumMapMap.hs
{-# LANGUAGE BangPatterns, GeneralizedNewtypeDeriving, TypeOperators #-}
-- | This compares the speed of 'Data.IntMap' functions with the speed of
-- 'Data.EnumMapMap.Strict' functions.
import Control.DeepSeq
import Control.Exception (evaluate)
import Control.Monad.Trans (liftIO)
import Criterion.Config
import Criterion.Main
import Data.List (foldl')
import Data.Maybe (fromMaybe)
import Data.IntMap (IntMap)
import qualified Data.IntMap as IM
import Data.EnumMapMap.Strict(EnumMapMap, (:&)(..), K(..))
import qualified Data.EnumMapMap.Strict as EMM
newtype ID = ID Int
deriving (Eq, Enum, Show, Num)
main :: IO()
main = do
let im :: IntMap Int
im = IM.fromAscList elemsIm
imAr :: [IntMap Int]
imAr = map IM.fromAscList elemsArIm
emm :: EnumMapMap (K ID) Int
emm = EMM.fromList elemsEmm
emmAr :: [EnumMapMap (K ID) Int]
emmAr = map EMM.fromList elemsArEmm
defaultMainWith
defaultConfig
(liftIO . evaluate $ rnf $ im :& emm :& imAr :& emmAr)
[ bench "lookup IM" $ whnf (lookupIm keysIm) im
, bench "lookup EMM" $ whnf (lookupEmm keysEmm) emm
, bench "insert IM" $ whnf (insIm elemsIm) IM.empty
, bench "insert EMM" $ whnf (insEmm elemsEmm) EMM.empty
, bench "delete IM" $ whnf (delIm keysIm) im
, bench "delete EMM" $ whnf (delEmm keysEmm) emm
, bench "union IM" $ nf (dual IM.union im) imAr
, bench "union EMM" $ nf (dual EMM.union emm) emmAr
, bench "difference IM" $ nf (dual IM.difference im) imAr
, bench "difference EMM" $ nf (dual EMM.difference emm) emmAr
, bench "intersection IM" $ nf (dual IM.intersection im) imAr
, bench "intersection EMM" $ nf (dual EMM.intersection emm) emmAr
]
where
elemsIm = zip keysIm values
elemsEmm = zip keysEmm values
elemsArIm = map (\ks -> zip ks values) keysArIm
elemsArEmm = map (\ks -> zip ks values) keysArEmm
keysIm :: [Int]
keysIm = [1..2^12]
keysArIm :: [[Int]]
keysArIm = do
i <- [1..2^5]
return $ do
j <- [1..(2^8)]
return $ j * i
keysEmm :: [K ID]
keysEmm = map (K . ID) keysIm
keysArEmm :: [[K ID]]
keysArEmm = map (map (K . ID)) keysArIm
values :: [Int]
values = [1..2^12]
lookupIm :: [Int] -> IntMap Int -> Int
lookupIm xs im = foldl' (\n k -> fromMaybe n (IM.lookup k im)) 0 xs
lookupEmm :: [K ID] -> EnumMapMap (K ID) Int -> Int
lookupEmm xs emm = foldl' (\n k -> fromMaybe n (EMM.lookup k emm)) 0 xs
insIm :: [(Int, Int)] -> IntMap Int -> IntMap Int
insIm xs m = foldl' (\m (k, v) -> v `seq` IM.insert k v m) m xs
insEmm :: [(K ID, Int)] -> EnumMapMap (K ID) Int -> EnumMapMap (K ID) Int
insEmm xs m = foldl' (\m (k, v) -> EMM.insert k v m) m xs
delIm :: [Int] -> IntMap Int -> IntMap Int
delIm xs m = foldl' (\m k -> IM.delete k m) m xs
delEmm :: [K ID] -> EnumMapMap (K ID) Int -> EnumMapMap (K ID) Int
delEmm xs m = foldl' (\m k -> EMM.delete k m) m xs
dual :: (a -> a -> a) -> a -> [a] -> [a]
dual f i = map $! f i