Force the components of returned pairs
[packages/containers.git] / benchmarks / Map.hs
1 {-# LANGUAGE BangPatterns #-}
2 module Main where
3
4 import Control.DeepSeq
5 import Control.Exception (evaluate)
6 import Control.Monad.Trans (liftIO)
7 import Criterion.Config
8 import Criterion.Main
9 import Data.List (foldl')
10 import qualified Data.Map as M
11 import Data.Maybe (fromMaybe)
12 import Prelude hiding (lookup)
13
14 main = do
15 let m = M.fromAscList elems :: M.Map Int Int
16 m_even = M.fromAscList elems_even :: M.Map Int Int
17 m_odd = M.fromAscList elems_odd :: M.Map Int Int
18 defaultMainWith
19 defaultConfig
20 (liftIO . evaluate $ rnf [m, m_even, m_odd])
21 [ bench "lookup absent" $ whnf (lookup evens) m_odd
22 , bench "lookup present" $ whnf (lookup evens) m_even
23 , bench "insert absent" $ whnf (ins elems_even) m_odd
24 , bench "insert present" $ whnf (ins elems_even) m_even
25 , bench "insertWith absent" $ whnf (insWith elems_even) m_odd
26 , bench "insertWith present" $ whnf (insWith elems_even) m_even
27 , bench "insertWith' absent" $ whnf (insWith' elems_even) m_odd
28 , bench "insertWith' present" $ whnf (insWith' elems_even) m_even
29 , bench "insertWithKey absent" $ whnf (insWithKey elems_even) m_odd
30 , bench "insertWithKey present" $ whnf (insWithKey elems_even) m_even
31 , bench "insertWithKey' absent" $ whnf (insWithKey' elems_even) m_odd
32 , bench "insertWithKey' present" $ whnf (insWithKey' elems_even) m_even
33 , bench "insertLookupWithKey absent" $ whnf (insLookupWithKey elems_even) m_odd
34 , bench "insertLookupWithKey present" $ whnf (insLookupWithKey elems_even) m_even
35 , bench "insertLookupWithKey' absent" $ whnf (insLookupWithKey' elems_even) m_odd
36 , bench "insertLookupWithKey' present" $ whnf (insLookupWithKey' elems_even) m_even
37 , bench "map" $ whnf (M.map (+ 1)) m
38 , bench "mapWithKey" $ whnf (M.mapWithKey (+)) m
39 , bench "foldlWithKey" $ whnf (ins elems) m
40 -- , bench "foldlWithKey'" $ whnf (M.foldlWithKey' sum 0) m
41 , bench "foldrWithKey" $ whnf (M.foldrWithKey consPair []) m
42 , bench "delete absent" $ whnf (del evens) m_odd
43 , bench "delete present" $ whnf (del evens) m
44 , bench "update absent" $ whnf (upd Just evens) m_odd
45 , bench "update present" $ whnf (upd Just evens) m_even
46 , bench "update delete" $ whnf (upd (const Nothing) evens) m
47 , bench "updateLookupWithKey absent" $ whnf (upd' Just evens) m_odd
48 , bench "updateLookupWithKey present" $ whnf (upd' Just evens) m_even
49 , bench "updateLookupWithKey delete" $ whnf (upd' (const Nothing) evens) m
50 , bench "alter absent" $ whnf (alt id evens) m_odd
51 , bench "alter insert" $ whnf (alt (const (Just 1)) evens) m_odd
52 , bench "alter update" $ whnf (alt id evens) m_even
53 , bench "alter delete" $ whnf (alt (const Nothing) evens) m
54 , bench "mapMaybe" $ whnf (M.mapMaybe maybeDel) m
55 , bench "mapMaybeWithKey" $ whnf (M.mapMaybeWithKey (const maybeDel)) m
56 , bench "lookupIndex" $ whnf (lookupIndex keys) m
57 , bench "union" $ whnf (M.union m_even) m_odd
58 , bench "difference" $ whnf (M.difference m) m_even
59 , bench "intersection" $ whnf (M.intersection m) m_even
60 , bench "split" $ whnf (M.split (bound `div` 2)) m
61 ]
62 where
63 bound = 2^10
64 elems = zip keys values
65 elems_even = zip evens evens
66 elems_odd = zip odds odds
67 keys = [1..bound]
68 evens = [2,4..bound]
69 odds = [1,3..bound]
70 values = [1..bound]
71 sum k v1 v2 = k + v1 + v2
72 consPair k v xs = (k, v) : xs
73
74 add3 :: Int -> Int -> Int -> Int
75 add3 x y z = x + y + z
76 {-# INLINE add3 #-}
77
78 lookup :: [Int] -> M.Map Int Int -> Int
79 lookup xs m = foldl' (\n k -> fromMaybe n (M.lookup k m)) 0 xs
80
81 lookupIndex :: [Int] -> M.Map Int Int -> Int
82 lookupIndex xs m = foldl' (\n k -> fromMaybe n (M.lookupIndex k m)) 0 xs
83
84 ins :: [(Int, Int)] -> M.Map Int Int -> M.Map Int Int
85 ins xs m = foldl' (\m (k, v) -> M.insert k v m) m xs
86
87 insWith :: [(Int, Int)] -> M.Map Int Int -> M.Map Int Int
88 insWith xs m = foldl' (\m (k, v) -> M.insertWith (+) k v m) m xs
89
90 insWithKey :: [(Int, Int)] -> M.Map Int Int -> M.Map Int Int
91 insWithKey xs m = foldl' (\m (k, v) -> M.insertWithKey add3 k v m) m xs
92
93 insWith' :: [(Int, Int)] -> M.Map Int Int -> M.Map Int Int
94 insWith' xs m = foldl' (\m (k, v) -> M.insertWith' (+) k v m) m xs
95
96 insWithKey' :: [(Int, Int)] -> M.Map Int Int -> M.Map Int Int
97 insWithKey' xs m = foldl' (\m (k, v) -> M.insertWithKey' add3 k v m) m xs
98
99 data PairS a b = PS !a !b
100
101 insLookupWithKey :: [(Int, Int)] -> M.Map Int Int -> (Int, M.Map Int Int)
102 insLookupWithKey xs m = let !(PS a b) = foldl' f (PS 0 m) xs in (a, b)
103 where
104 f (PS n m) (k, v) = let !(n', m') = M.insertLookupWithKey add3 k v m
105 in PS (fromMaybe 0 n' + n) m'
106
107 insLookupWithKey' :: [(Int, Int)] -> M.Map Int Int -> (Int, M.Map Int Int)
108 insLookupWithKey' xs m = let !(PS a b) = foldl' f (PS 0 m) xs in (a, b)
109 where
110 f (PS n m) (k, v) = let !(n', m') = M.insertLookupWithKey' add3 k v m
111 in PS (fromMaybe 0 n' + n) m'
112
113 del :: [Int] -> M.Map Int Int -> M.Map Int Int
114 del xs m = foldl' (\m k -> M.delete k m) m xs
115
116 upd :: (Int -> Maybe Int) -> [Int] -> M.Map Int Int -> M.Map Int Int
117 upd f xs m = foldl' (\m k -> M.update f k m) m xs
118
119 upd' :: (Int -> Maybe Int) -> [Int] -> M.Map Int Int -> M.Map Int Int
120 upd' f xs m = foldl' (\m k -> snd $ M.updateLookupWithKey (\_ a -> f a) k m) m xs
121
122 alt :: (Maybe Int -> Maybe Int) -> [Int] -> M.Map Int Int -> M.Map Int Int
123 alt f xs m = foldl' (\m k -> M.alter f k m) m xs
124
125 maybeDel :: Int -> Maybe Int
126 maybeDel n | n `mod` 3 == 0 = Nothing
127 | otherwise = Just n