Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 369 lines (324 sloc) 13.816 kb
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
1 {-# LANGUAGE CPP, DeriveGeneric, GADTs, PackageImports, RecordWildCards #-}
a389553 @tibbe Added benchmarks for ByteStrings
authored
2
7df2d6c @tibbe Added some initial benchmarks
authored
3 module Main where
4
5 import Control.DeepSeq
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
6 import Control.DeepSeq.Generics (genericRnf)
7 import Criterion.Main (bench, bgroup, defaultMain, env, nf, whnf)
7490830 @tibbe Switch back to the Patricia trie implementation
authored
8 import Data.Bits ((.&.))
980262c @tibbe -Wall police
authored
9 import Data.Hashable (Hashable)
a389553 @tibbe Added benchmarks for ByteStrings
authored
10 import qualified Data.ByteString as BS
dea3220 @tibbe Add benchmarks for hashmap package comparison
authored
11 import qualified "hashmap" Data.HashMap as IHM
27b193e @tibbe Finish D.H.Strict
authored
12 import qualified Data.HashMap.Strict as HM
f843e01 @tibbe Added benchmark for IntMap
authored
13 import qualified Data.IntMap as IM
a389553 @tibbe Added benchmarks for ByteStrings
authored
14 import qualified Data.Map as M
7df2d6c @tibbe Added some initial benchmarks
authored
15 import Data.List (foldl')
16 import Data.Maybe (fromMaybe)
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
17 import GHC.Generics (Generic)
7df2d6c @tibbe Added some initial benchmarks
authored
18 import Prelude hiding (lookup)
19
a389553 @tibbe Added benchmarks for ByteStrings
authored
20 import qualified Util.ByteString as UBS
f843e01 @tibbe Added benchmark for IntMap
authored
21 import qualified Util.Int as UI
22 import qualified Util.String as US
7df2d6c @tibbe Added some initial benchmarks
authored
23
61257d3 @bos Build benchmarks with bytestring >= 0.10
bos authored
24 #if !MIN_VERSION_bytestring(0,10,0)
a389553 @tibbe Added benchmarks for ByteStrings
authored
25 instance NFData BS.ByteString
61257d3 @bos Build benchmarks with bytestring >= 0.10
bos authored
26 #endif
7df2d6c @tibbe Added some initial benchmarks
authored
27
a389553 @tibbe Added benchmarks for ByteStrings
authored
28 data B where
29 B :: NFData a => a -> B
7df2d6c @tibbe Added some initial benchmarks
authored
30
a389553 @tibbe Added benchmarks for ByteStrings
authored
31 instance NFData B where
32 rnf (B b) = rnf b
7df2d6c @tibbe Added some initial benchmarks
authored
33
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
34 -- TODO: This a stopgap measure to keep the benchmark work with
35 -- Criterion 1.0.
36 data Env = Env {
37 n :: !Int,
38
39 elems :: ![(String, Int)],
40 keys :: ![String],
41 elemsBS :: ![(BS.ByteString, Int)],
42 keysBS :: ![BS.ByteString],
43 elemsI :: ![(Int, Int)],
44 keysI :: ![Int],
45 elemsI2 :: ![(Int, Int)], -- for union
46
47 keys' :: ![String],
48 keysBS' :: ![BS.ByteString],
49 keysI' :: ![Int],
50
51 keysDup :: ![String],
52 keysDupBS :: ![BS.ByteString],
53 keysDupI :: ![Int],
54 elemsDup :: ![(String, Int)],
55 elemsDupBS :: ![(BS.ByteString, Int)],
56 elemsDupI :: ![(Int, Int)],
57
58 hm :: !(HM.HashMap String Int),
59 hmbs :: !(HM.HashMap BS.ByteString Int),
60 hmi :: !(HM.HashMap Int Int),
61 hmi2 :: !(HM.HashMap Int Int),
62 m :: !(M.Map String Int),
63 mbs :: !(M.Map BS.ByteString Int),
64 im :: !(IM.IntMap Int),
65 ihm :: !(IHM.Map String Int),
66 ihmbs :: !(IHM.Map BS.ByteString Int)
67 } deriving Generic
68
69 instance NFData Env where rnf = genericRnf
70
71 setupEnv :: IO Env
72 setupEnv = do
73 let n = 2^(12 :: Int)
74
75 elems = zip keys [1..n]
76 keys = US.rnd 8 n
77 elemsBS = zip keysBS [1..n]
78 keysBS = UBS.rnd 8 n
79 elemsI = zip keysI [1..n]
80 keysI = UI.rnd (n+n) n
81 elemsI2 = zip [n `div` 2..n + (n `div` 2)] [1..n] -- for union
82
83 keys' = US.rnd' 8 n
84 keysBS' = UBS.rnd' 8 n
85 keysI' = UI.rnd' (n+n) n
86
87 keysDup = US.rnd 2 n
88 keysDupBS = UBS.rnd 2 n
89 keysDupI = UI.rnd (n`div`4) n
90 elemsDup = zip keysDup [1..n]
91 elemsDupBS = zip keysDupBS [1..n]
92 elemsDupI = zip keysDupI [1..n]
93
94 hm = HM.fromList elems
95 hmbs = HM.fromList elemsBS
96 hmi = HM.fromList elemsI
97 hmi2 = HM.fromList elemsI2
98 m = M.fromList elems
99 mbs = M.fromList elemsBS
100 im = IM.fromList elemsI
101 ihm = IHM.fromList elems
102 ihmbs = IHM.fromList elemsBS
103 return Env{..}
104
980262c @tibbe -Wall police
authored
105 main :: IO ()
7df2d6c @tibbe Added some initial benchmarks
authored
106 main = do
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
107 defaultMain
f843e01 @tibbe Added benchmark for IntMap
authored
108 [
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
109 env setupEnv $ \ ~(Env{..}) ->
f843e01 @tibbe Added benchmark for IntMap
authored
110 -- * Comparison to other data structures
111 -- ** Map
112 bgroup "Map"
113 [ bgroup "lookup"
32f3867 @tibbe Evaluate to WHNF instead of NF in benchmarks
authored
114 [ bench "String" $ whnf (lookupM keys) m
115 , bench "ByteString" $ whnf (lookupM keysBS) mbs
5b48337 @tibbe Benchmark Maps of Strings as well
authored
116 ]
29feedc @jmaessen Add benchmarks that measure misses and overlaps.
jmaessen authored
117 , bgroup "lookup-miss"
118 [ bench "String" $ whnf (lookupM keys') m
119 , bench "ByteString" $ whnf (lookupM keysBS') mbs
120 ]
f843e01 @tibbe Added benchmark for IntMap
authored
121 , bgroup "insert"
32f3867 @tibbe Evaluate to WHNF instead of NF in benchmarks
authored
122 [ bench "String" $ whnf (insertM elems) M.empty
123 , bench "ByteStringString" $ whnf (insertM elemsBS) M.empty
5b48337 @tibbe Benchmark Maps of Strings as well
authored
124 ]
29feedc @jmaessen Add benchmarks that measure misses and overlaps.
jmaessen authored
125 , bgroup "insert-dup"
126 [ bench "String" $ whnf (insertM elems) m
127 , bench "ByteStringString" $ whnf (insertM elemsBS) mbs
128 ]
f843e01 @tibbe Added benchmark for IntMap
authored
129 , bgroup "delete"
29feedc @jmaessen Add benchmarks that measure misses and overlaps.
jmaessen authored
130 [ bench "String" $ whnf (deleteM keys) m
131 , bench "ByteString" $ whnf (deleteM keysBS) mbs
132 ]
133 , bgroup "delete-miss"
134 [ bench "String" $ whnf (deleteM keys') m
135 , bench "ByteString" $ whnf (deleteM keysBS') mbs
5b48337 @tibbe Benchmark Maps of Strings as well
authored
136 ]
ab032fe @jmaessen Added benchmarks for size.
jmaessen authored
137 , bgroup "size"
138 [ bench "String" $ whnf M.size m
139 , bench "ByteString" $ whnf M.size mbs
140 ]
ecafc30 @jmaessen Benchmarks for fromList
jmaessen authored
141 , bgroup "fromList"
142 [ bench "String" $ whnf M.fromList elems
143 , bench "ByteString" $ whnf M.fromList elemsBS
144 ]
a389553 @tibbe Added benchmarks for ByteStrings
authored
145 ]
f843e01 @tibbe Added benchmark for IntMap
authored
146
f9bf52f @tibbe benchmarks: rename hashmap/HashMap to hashmap/Map
authored
147 -- ** Map from the hashmap package
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
148 , env setupEnv $ \ ~(Env{..}) ->
149 bgroup "hashmap/Map"
dea3220 @tibbe Add benchmarks for hashmap package comparison
authored
150 [ bgroup "lookup"
151 [ bench "String" $ whnf (lookupIHM keys) ihm
152 , bench "ByteString" $ whnf (lookupIHM keysBS) ihmbs
153 ]
154 , bgroup "lookup-miss"
155 [ bench "String" $ whnf (lookupIHM keys') ihm
156 , bench "ByteString" $ whnf (lookupIHM keysBS') ihmbs
157 ]
158 , bgroup "insert"
159 [ bench "String" $ whnf (insertIHM elems) IHM.empty
160 , bench "ByteStringString" $ whnf (insertIHM elemsBS) IHM.empty
161 ]
162 , bgroup "insert-dup"
163 [ bench "String" $ whnf (insertIHM elems) ihm
164 , bench "ByteStringString" $ whnf (insertIHM elemsBS) ihmbs
165 ]
166 , bgroup "delete"
167 [ bench "String" $ whnf (deleteIHM keys) ihm
168 , bench "ByteString" $ whnf (deleteIHM keysBS) ihmbs
169 ]
170 , bgroup "delete-miss"
171 [ bench "String" $ whnf (deleteIHM keys') ihm
172 , bench "ByteString" $ whnf (deleteIHM keysBS') ihmbs
173 ]
174 , bgroup "size"
175 [ bench "String" $ whnf IHM.size ihm
176 , bench "ByteString" $ whnf IHM.size ihmbs
177 ]
178 , bgroup "fromList"
179 [ bench "String" $ whnf IHM.fromList elems
180 , bench "ByteString" $ whnf IHM.fromList elemsBS
181 ]
182 ]
183
f843e01 @tibbe Added benchmark for IntMap
authored
184 -- ** IntMap
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
185 , env setupEnv $ \ ~(Env{..}) ->
186 bgroup "IntMap"
32f3867 @tibbe Evaluate to WHNF instead of NF in benchmarks
authored
187 [ bench "lookup" $ whnf (lookupIM keysI) im
29feedc @jmaessen Add benchmarks that measure misses and overlaps.
jmaessen authored
188 , bench "lookup-miss" $ whnf (lookupIM keysI') im
32f3867 @tibbe Evaluate to WHNF instead of NF in benchmarks
authored
189 , bench "insert" $ whnf (insertIM elemsI) IM.empty
29feedc @jmaessen Add benchmarks that measure misses and overlaps.
jmaessen authored
190 , bench "insert-dup" $ whnf (insertIM elemsI) im
32f3867 @tibbe Evaluate to WHNF instead of NF in benchmarks
authored
191 , bench "delete" $ whnf (deleteIM keysI) im
29feedc @jmaessen Add benchmarks that measure misses and overlaps.
jmaessen authored
192 , bench "delete-miss" $ whnf (deleteIM keysI') im
ab032fe @jmaessen Added benchmarks for size.
jmaessen authored
193 , bench "size" $ whnf IM.size im
ecafc30 @jmaessen Benchmarks for fromList
jmaessen authored
194 , bench "fromList" $ whnf IM.fromList elemsI
f843e01 @tibbe Added benchmark for IntMap
authored
195 ]
196
ab13997 @tibbe Switch benchmarks to Criterion 1.0
authored
197 , env setupEnv $ \ ~(Env{..}) ->
198 bgroup "HashMap"
d878802 @tibbe Group all HashMap benchmarks
authored
199 [ -- * Basic interface
200 bgroup "lookup"
201 [ bench "String" $ whnf (lookup keys) hm
202 , bench "ByteString" $ whnf (lookup keysBS) hmbs
203 , bench "Int" $ whnf (lookup keysI) hmi
204 ]
205 , bgroup "lookup-miss"
206 [ bench "String" $ whnf (lookup keys') hm
207 , bench "ByteString" $ whnf (lookup keysBS') hmbs
208 , bench "Int" $ whnf (lookup keysI') hmi
209 ]
210 , bgroup "insert"
211 [ bench "String" $ whnf (insert elems) HM.empty
212 , bench "ByteString" $ whnf (insert elemsBS) HM.empty
213 , bench "Int" $ whnf (insert elemsI) HM.empty
214 ]
215 , bgroup "insert-dup"
216 [ bench "String" $ whnf (insert elems) hm
217 , bench "ByteString" $ whnf (insert elemsBS) hmbs
218 , bench "Int" $ whnf (insert elemsI) hmi
219 ]
220 , bgroup "delete"
221 [ bench "String" $ whnf (delete keys) hm
222 , bench "ByteString" $ whnf (delete keysBS) hmbs
223 , bench "Int" $ whnf (delete keysI) hmi
224 ]
225 , bgroup "delete-miss"
226 [ bench "String" $ whnf (delete keys') hm
227 , bench "ByteString" $ whnf (delete keysBS') hmbs
228 , bench "Int" $ whnf (delete keysI') hmi
229 ]
7490830 @tibbe Switch back to the Patricia trie implementation
authored
230
d878802 @tibbe Group all HashMap benchmarks
authored
231 -- Combine
232 , bench "union" $ whnf (HM.union hmi) hmi2
0d2d721 @tibbe Add 'union' and a Monoid instance
authored
233
d878802 @tibbe Group all HashMap benchmarks
authored
234 -- Transformations
235 , bench "map" $ whnf (HM.map (\ v -> v + 1)) hmi
7490830 @tibbe Switch back to the Patricia trie implementation
authored
236
d878802 @tibbe Group all HashMap benchmarks
authored
237 -- * Difference and intersection
238 , bench "difference" $ whnf (HM.difference hmi) hmi2
239 , bench "intersection" $ whnf (HM.intersection hmi) hmi2
f449e37 @tibbe Backport benchmarks for difference and intersection
authored
240
d878802 @tibbe Group all HashMap benchmarks
authored
241 -- Folds
242 , bench "foldl'" $ whnf (HM.foldl' (+) 0) hmi
243 , bench "foldr" $ nf (HM.foldr (:) []) hmi
7490830 @tibbe Switch back to the Patricia trie implementation
authored
244
d878802 @tibbe Group all HashMap benchmarks
authored
245 -- Filter
246 , bench "filter" $ whnf (HM.filter (\ v -> v .&. 1 == 0)) hmi
247 , bench "filterWithKey" $ whnf (HM.filterWithKey (\ k _ -> k .&. 1 == 0)) hmi
ab032fe @jmaessen Added benchmarks for size.
jmaessen authored
248
d878802 @tibbe Group all HashMap benchmarks
authored
249 -- Size
250 , bgroup "size"
251 [ bench "String" $ whnf HM.size hm
252 , bench "ByteString" $ whnf HM.size hmbs
253 , bench "Int" $ whnf HM.size hmi
254 ]
ecafc30 @jmaessen Benchmarks for fromList
jmaessen authored
255
d878802 @tibbe Group all HashMap benchmarks
authored
256 -- fromList
257 , bgroup "fromList"
5f322e0 @tibbe Remove slow fromList[With] benchmarks
authored
258 [ bgroup "long"
259 [ bench "String" $ whnf HM.fromList elems
260 , bench "ByteString" $ whnf HM.fromList elemsBS
261 , bench "Int" $ whnf HM.fromList elemsI
262 ]
263 , bgroup "short"
264 [ bench "String" $ whnf HM.fromList elemsDup
265 , bench "ByteString" $ whnf HM.fromList elemsDupBS
266 , bench "Int" $ whnf HM.fromList elemsDupI
36a6c90 @twanvl Compare different implementations of fromList
twanvl authored
267 ]
268 ]
5f322e0 @tibbe Remove slow fromList[With] benchmarks
authored
269 -- fromListWith
d878802 @tibbe Group all HashMap benchmarks
authored
270 , bgroup "fromListWith"
5f322e0 @tibbe Remove slow fromList[With] benchmarks
authored
271 [ bgroup "long"
272 [ bench "String" $ whnf (HM.fromListWith (+)) elems
273 , bench "ByteString" $ whnf (HM.fromListWith (+)) elemsBS
274 , bench "Int" $ whnf (HM.fromListWith (+)) elemsI
275 ]
276 , bgroup "short"
277 [ bench "String" $ whnf (HM.fromListWith (+)) elemsDup
278 , bench "ByteString" $ whnf (HM.fromListWith (+)) elemsDupBS
279 , bench "Int" $ whnf (HM.fromListWith (+)) elemsDupI
203439e @tibbe Add benchmarks for fromListWith
authored
280 ]
281 ]
ecafc30 @jmaessen Benchmarks for fromList
jmaessen authored
282 ]
a389553 @tibbe Added benchmarks for ByteStrings
authored
283 ]
36a6c90 @twanvl Compare different implementations of fromList
twanvl authored
284
7df2d6c @tibbe Added some initial benchmarks
authored
285 ------------------------------------------------------------------------
286 -- * HashMap
287
a389553 @tibbe Added benchmarks for ByteStrings
authored
288 lookup :: (Eq k, Hashable k) => [k] -> HM.HashMap k Int -> Int
289 lookup xs m = foldl' (\z k -> fromMaybe z (HM.lookup k m)) 0 xs
f843e01 @tibbe Added benchmark for IntMap
authored
290 {-# SPECIALIZE lookup :: [Int] -> HM.HashMap Int Int -> Int #-}
a389553 @tibbe Added benchmarks for ByteStrings
authored
291 {-# SPECIALIZE lookup :: [String] -> HM.HashMap String Int -> Int #-}
292 {-# SPECIALIZE lookup :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
293 -> Int #-}
294
295 insert :: (Eq k, Hashable k) => [(k, Int)] -> HM.HashMap k Int
296 -> HM.HashMap k Int
297 insert xs m0 = foldl' (\m (k, v) -> HM.insert k v m) m0 xs
f843e01 @tibbe Added benchmark for IntMap
authored
298 {-# SPECIALIZE insert :: [(Int, Int)] -> HM.HashMap Int Int
299 -> HM.HashMap Int Int #-}
a389553 @tibbe Added benchmarks for ByteStrings
authored
300 {-# SPECIALIZE insert :: [(String, Int)] -> HM.HashMap String Int
301 -> HM.HashMap String Int #-}
302 {-# SPECIALIZE insert :: [(BS.ByteString, Int)] -> HM.HashMap BS.ByteString Int
303 -> HM.HashMap BS.ByteString Int #-}
304
7490830 @tibbe Switch back to the Patricia trie implementation
authored
305 delete :: (Eq k, Hashable k) => [k] -> HM.HashMap k Int -> HM.HashMap k Int
306 delete xs m0 = foldl' (\m k -> HM.delete k m) m0 xs
307 {-# SPECIALIZE delete :: [Int] -> HM.HashMap Int Int -> HM.HashMap Int Int #-}
308 {-# SPECIALIZE delete :: [String] -> HM.HashMap String Int
309 -> HM.HashMap String Int #-}
310 {-# SPECIALIZE delete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
311 -> HM.HashMap BS.ByteString Int #-}
4a75ae3 @tibbe Implement bulk creation using mutation behind the scenes
authored
312
7df2d6c @tibbe Added some initial benchmarks
authored
313 ------------------------------------------------------------------------
314 -- * Map
315
a389553 @tibbe Added benchmarks for ByteStrings
authored
316 lookupM :: Ord k => [k] -> M.Map k Int -> Int
317 lookupM xs m = foldl' (\z k -> fromMaybe z (M.lookup k m)) 0 xs
318 {-# SPECIALIZE lookupM :: [String] -> M.Map String Int -> Int #-}
319 {-# SPECIALIZE lookupM :: [BS.ByteString] -> M.Map BS.ByteString Int -> Int #-}
7df2d6c @tibbe Added some initial benchmarks
authored
320
a389553 @tibbe Added benchmarks for ByteStrings
authored
321 insertM :: Ord k => [(k, Int)] -> M.Map k Int -> M.Map k Int
322 insertM xs m0 = foldl' (\m (k, v) -> M.insert k v m) m0 xs
323 {-# SPECIALIZE insertM :: [(String, Int)] -> M.Map String Int
324 -> M.Map String Int #-}
325 {-# SPECIALIZE insertM :: [(BS.ByteString, Int)] -> M.Map BS.ByteString Int
326 -> M.Map BS.ByteString Int #-}
7df2d6c @tibbe Added some initial benchmarks
authored
327
a389553 @tibbe Added benchmarks for ByteStrings
authored
328 deleteM :: Ord k => [k] -> M.Map k Int -> M.Map k Int
329 deleteM xs m0 = foldl' (\m k -> M.delete k m) m0 xs
330 {-# SPECIALIZE deleteM :: [String] -> M.Map String Int -> M.Map String Int #-}
331 {-# SPECIALIZE deleteM :: [BS.ByteString] -> M.Map BS.ByteString Int
332 -> M.Map BS.ByteString Int #-}
7df2d6c @tibbe Added some initial benchmarks
authored
333
334 ------------------------------------------------------------------------
f9bf52f @tibbe benchmarks: rename hashmap/HashMap to hashmap/Map
authored
335 -- * Map from the hashmap package
dea3220 @tibbe Add benchmarks for hashmap package comparison
authored
336
337 lookupIHM :: (Eq k, Hashable k, Ord k) => [k] -> IHM.Map k Int -> Int
338 lookupIHM xs m = foldl' (\z k -> fromMaybe z (IHM.lookup k m)) 0 xs
339 {-# SPECIALIZE lookupIHM :: [String] -> IHM.Map String Int -> Int #-}
340 {-# SPECIALIZE lookupIHM :: [BS.ByteString] -> IHM.Map BS.ByteString Int
341 -> Int #-}
342
343 insertIHM :: (Eq k, Hashable k, Ord k) => [(k, Int)] -> IHM.Map k Int
344 -> IHM.Map k Int
345 insertIHM xs m0 = foldl' (\m (k, v) -> IHM.insert k v m) m0 xs
346 {-# SPECIALIZE insertIHM :: [(String, Int)] -> IHM.Map String Int
347 -> IHM.Map String Int #-}
348 {-# SPECIALIZE insertIHM :: [(BS.ByteString, Int)] -> IHM.Map BS.ByteString Int
349 -> IHM.Map BS.ByteString Int #-}
350
351 deleteIHM :: (Eq k, Hashable k, Ord k) => [k] -> IHM.Map k Int -> IHM.Map k Int
352 deleteIHM xs m0 = foldl' (\m k -> IHM.delete k m) m0 xs
353 {-# SPECIALIZE deleteIHM :: [String] -> IHM.Map String Int
354 -> IHM.Map String Int #-}
355 {-# SPECIALIZE deleteIHM :: [BS.ByteString] -> IHM.Map BS.ByteString Int
356 -> IHM.Map BS.ByteString Int #-}
357
358 ------------------------------------------------------------------------
f843e01 @tibbe Added benchmark for IntMap
authored
359 -- * IntMap
360
361 lookupIM :: [Int] -> IM.IntMap Int -> Int
362 lookupIM xs m = foldl' (\z k -> fromMaybe z (IM.lookup k m)) 0 xs
363
364 insertIM :: [(Int, Int)] -> IM.IntMap Int -> IM.IntMap Int
365 insertIM xs m0 = foldl' (\m (k, v) -> IM.insert k v m) m0 xs
366
367 deleteIM :: [Int] -> IM.IntMap Int -> IM.IntMap Int
368 deleteIM xs m0 = foldl' (\m k -> IM.delete k m) m0 xs
Something went wrong with that request. Please try again.