@@ -10,8 +10,11 @@ import Data.Hashable (Hashable)
10
10
import qualified Data.ByteString as BS
11
11
import qualified "hashmap" Data.HashMap as IHM
12
12
import qualified Data.HashMap.Strict as HM
13
+ import qualified Data.HashSet as HS
13
14
import qualified Data.IntMap as IM
14
15
import qualified Data.Map as M
16
+ import qualified Data.Set as S
17
+ import qualified Data.Vector as V
15
18
import Data.List (foldl' )
16
19
import Data.Maybe (fromMaybe )
17
20
import GHC.Generics (Generic )
@@ -36,6 +39,8 @@ instance NFData B where
36
39
data Env = Env {
37
40
n :: ! Int ,
38
41
42
+ csz :: ! Int , -- container size
43
+
39
44
elems :: ! [(String , Int )],
40
45
keys :: ! [String ],
41
46
elemsBS :: ! [(BS. ByteString , Int )],
@@ -48,6 +53,11 @@ data Env = Env {
48
53
keysBS' :: ! [BS. ByteString ],
49
54
keysI' :: ! [Int ],
50
55
56
+ listOfHMs :: ! [HM. HashMap Int Int ],
57
+ vecOfHMs :: ! (V. Vector (HM. HashMap Int Int )),
58
+ hsetOfHMs :: ! (HS. HashSet (HM. HashMap Int Int )),
59
+ setOfHMs :: ! (S. Set (HM. HashMap Int Int )),
60
+
51
61
keysDup :: ! [String ],
52
62
keysDupBS :: ! [BS. ByteString ],
53
63
keysDupI :: ! [Int ],
@@ -72,6 +82,20 @@ setupEnv :: IO Env
72
82
setupEnv = do
73
83
let n = 2 ^ (12 :: Int )
74
84
85
+ -- When building a container of hashmaps, 'cn' will be the size of each.
86
+ cn = n `div` 16
87
+ -- 'csz' is the size of the container of hashmaps.
88
+ csz = 2 ^ (7 :: Int )
89
+
90
+ values = [1 .. csz* cn]
91
+
92
+ chop _ [] = []
93
+ chop k l =
94
+ let (taken, left) = splitAt k l
95
+ in taken : chop k left
96
+
97
+ vals = chop cn values
98
+
75
99
elems = zip keys [1 .. n]
76
100
keys = US. rnd 8 n
77
101
elemsBS = zip keysBS [1 .. n]
@@ -84,6 +108,11 @@ setupEnv = do
84
108
keysBS' = UBS. rnd' 8 n
85
109
keysI' = UI. rnd' (n+ n) n
86
110
111
+ listOfHMs = zipWith (\ x y -> HM. fromList (zip x y)) (repeat keysI) vals
112
+ vecOfHMs = V. fromList listOfHMs
113
+ hsetOfHMs = HS. fromList listOfHMs
114
+ setOfHMs = S. fromList listOfHMs
115
+
87
116
keysDup = US. rnd 2 n
88
117
keysDupBS = UBS. rnd 2 n
89
118
keysDupI = UI. rnd (n`div` 4 ) n
@@ -228,6 +257,57 @@ main = do
228
257
, bench " Int" $ whnf (delete keysI') hmi
229
258
]
230
259
260
+ , bgroup " containerized"
261
+ [ bgroup " lookup"
262
+ [ bench " List" $ nf (lookupC keysI) listOfHMs
263
+ , bench " Vector" $ nf (lookupC keysI) vecOfHMs
264
+ , bench " HashSet" $ nf (lookupHS keysI) hsetOfHMs
265
+ , bench " Set" $ nf (lookupS keysI) setOfHMs
266
+ ]
267
+ , bgroup " insert"
268
+ [ bench " List" $ nf (insertC elemsI) listOfHMs
269
+ , bench " Vector" $ nf (insertC elemsI) vecOfHMs
270
+ , bench " HashSet" $ nf (insertHS elemsI) hsetOfHMs
271
+ , bench " Set" $ nf (insertS elemsI) setOfHMs
272
+ ]
273
+ , bgroup " delete"
274
+ [ bench " List" $ nf (deleteC keysI) listOfHMs
275
+ , bench " Vector" $ nf (deleteC keysI) vecOfHMs
276
+ , bench " HashSet" $ nf (deleteHS keysI) hsetOfHMs
277
+ , bench " Set" $ nf (deleteS keysI) setOfHMs
278
+ ]
279
+ , bgroup " union"
280
+ [ bench " List" $ whnf unionC listOfHMs
281
+ , bench " Vector" $ whnf unionC vecOfHMs
282
+ , bench " HashSet" $ whnf unionC hsetOfHMs
283
+ , bench " Set" $ whnf unionC setOfHMs
284
+ ]
285
+ , bgroup " containerized map"
286
+ [ bench " List" $ nf (mapC (\ v -> v + 1 )) listOfHMs
287
+ , bench " Vector" $ nf (mapC (\ v -> v + 1 )) vecOfHMs
288
+ , bench " HashSet" $ nf (mapHS (\ v -> v + 1 )) hsetOfHMs
289
+ , bench " Set" $ nf (mapS (\ v -> v + 1 )) setOfHMs
290
+ ]
291
+ , bgroup " union"
292
+ [ bench " List" $ whnf unionC listOfHMs
293
+ , bench " Vector" $ whnf unionC vecOfHMs
294
+ , bench " HashSet" $ whnf unionC hsetOfHMs
295
+ , bench " Set" $ whnf unionC setOfHMs
296
+ ]
297
+ , bgroup " intersection"
298
+ [ bench " List" $ whnf intersectionC listOfHMs
299
+ , bench " Vector" $ whnf intersectionC vecOfHMs
300
+ , bench " HashSet" $ whnf intersectionC hsetOfHMs
301
+ , bench " Set" $ whnf intersectionC setOfHMs
302
+ ]
303
+ , bgroup " size"
304
+ [ bench " List" $ nf sizeC listOfHMs
305
+ , bench " Vector" $ nf sizeC vecOfHMs
306
+ , bench " HashSet" $ nf sizeHS hsetOfHMs
307
+ , bench " Set" $ nf sizeS setOfHMs
308
+ ]
309
+ ]
310
+
231
311
-- Combine
232
312
, bench " union" $ whnf (HM. union hmi) hmi2
233
313
@@ -292,6 +372,18 @@ lookup xs m = foldl' (\z k -> fromMaybe z (HM.lookup k m)) 0 xs
292
372
{-# SPECIALIZE lookup :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
293
373
-> Int #-}
294
374
375
+ lookupC :: (Eq k , Hashable k , Traversable f ) => [k ] -> f (HM. HashMap k Int ) -> f Int
376
+ lookupC = fmap . lookup
377
+ {-# SPECIALIZE lookupC :: [Int] -> [HM.HashMap Int Int] -> [Int] #-}
378
+ {-# SPECIALIZE lookupC :: [Int] -> V.Vector (HM.HashMap Int Int)
379
+ -> V.Vector Int #-}
380
+
381
+ lookupHS :: [Int ] -> HS. HashSet (HM. HashMap Int Int ) -> HS. HashSet Int
382
+ lookupHS = HS. map . lookup
383
+
384
+ lookupS :: [Int ] -> S. Set (HM. HashMap Int Int ) -> S. Set Int
385
+ lookupS = S. map . lookup
386
+
295
387
insert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
296
388
-> HM. HashMap k Int
297
389
insert xs m0 = foldl' (\ m (k, v) -> HM. insert k v m) m0 xs
@@ -302,6 +394,21 @@ insert xs m0 = foldl' (\m (k, v) -> HM.insert k v m) m0 xs
302
394
{-# SPECIALIZE insert :: [(BS.ByteString, Int)] -> HM.HashMap BS.ByteString Int
303
395
-> HM.HashMap BS.ByteString Int #-}
304
396
397
+ insertC :: (Eq k , Hashable k , Traversable f ) => [(k , Int )] -> f (HM. HashMap k Int )
398
+ -> f (HM. HashMap k Int )
399
+ insertC l = fmap (insert l)
400
+ {-# SPECIALIZE insertC :: [(Int, Int)] -> [HM.HashMap Int Int]
401
+ -> [HM.HashMap Int Int] #-}
402
+ {-# SPECIALIZE insertC :: [(Int, Int)] -> V.Vector (HM.HashMap Int Int)
403
+ -> V.Vector (HM.HashMap Int Int) #-}
404
+
405
+ insertHS :: [(Int , Int )] -> HS. HashSet (HM. HashMap Int Int )
406
+ -> HS. HashSet (HM. HashMap Int Int )
407
+ insertHS l = HS. map (insert l)
408
+
409
+ insertS :: [(Int , Int )] -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
410
+ insertS l = S. map (insert l)
411
+
305
412
delete :: (Eq k , Hashable k ) => [k ] -> HM. HashMap k Int -> HM. HashMap k Int
306
413
delete xs m0 = foldl' (\ m k -> HM. delete k m) m0 xs
307
414
{-# SPECIALIZE delete :: [Int] -> HM.HashMap Int Int -> HM.HashMap Int Int #-}
@@ -310,6 +417,66 @@ delete xs m0 = foldl' (\m k -> HM.delete k m) m0 xs
310
417
{-# SPECIALIZE delete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
311
418
-> HM.HashMap BS.ByteString Int #-}
312
419
420
+ deleteC :: (Eq k , Hashable k , Functor f ) => [k ] -> f (HM. HashMap k Int )
421
+ -> f (HM. HashMap k Int )
422
+ deleteC = fmap . delete
423
+ {-# SPECIALIZE deleteC :: [Int] -> [HM.HashMap Int Int]
424
+ -> [HM.HashMap Int Int] #-}
425
+ {-# SPECIALIZE deleteC :: [Int] -> V.Vector (HM.HashMap Int Int)
426
+ -> V.Vector (HM.HashMap Int Int) #-}
427
+
428
+ deleteHS :: [Int ] -> HS. HashSet (HM. HashMap Int Int )
429
+ -> HS. HashSet (HM. HashMap Int Int )
430
+ deleteHS = HS. map . delete
431
+
432
+ deleteS :: [Int ] -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
433
+ deleteS = S. map . delete
434
+
435
+ unionC :: (Eq k , Hashable k , Foldable f ) => f (HM. HashMap k Int )
436
+ -> HM. HashMap k Int
437
+ unionC = foldl' HM. union mempty
438
+ {-# SPECIALIZE unionC :: [HM.HashMap Int Int] -> HM.HashMap Int Int #-}
439
+ {-# SPECIALIZE unionC :: V.Vector (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
440
+ {-# SPECIALIZE unionC :: HS.HashSet (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
441
+ {-# SPECIALIZE unionC :: S.Set (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
442
+
443
+ mapC :: (Eq k , Hashable k , Functor f ) => (Int -> Int ) -> f (HM. HashMap k Int )
444
+ -> f (HM. HashMap k Int )
445
+ mapC f = fmap (HM. map f)
446
+ {-# SPECIALIZE mapC :: (Int -> Int) -> [HM.HashMap Int Int]
447
+ -> [HM.HashMap Int Int] #-}
448
+ {-# SPECIALIZE mapC :: (Int -> Int) -> V.Vector (HM.HashMap Int Int)
449
+ -> V.Vector (HM.HashMap Int Int) #-}
450
+
451
+ mapHS :: (Int -> Int ) -> HS. HashSet (HM. HashMap Int Int )
452
+ -> HS. HashSet (HM. HashMap Int Int )
453
+ mapHS f = HS. map (HM. map f)
454
+
455
+ mapS :: (Int -> Int ) -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
456
+ mapS f = S. map (HM. map f)
457
+
458
+ intersectionC :: (Eq k , Hashable k , Foldable f ) => f (HM. HashMap k Int )
459
+ -> HM. HashMap k Int
460
+ intersectionC = foldl' HM. intersection mempty
461
+ {-# SPECIALIZE intersectionC :: [HM.HashMap Int Int]
462
+ -> HM.HashMap Int Int #-}
463
+ {-# SPECIALIZE intersectionC :: V.Vector (HM.HashMap Int Int)
464
+ -> HM.HashMap Int Int #-}
465
+ {-# SPECIALIZE intersectionC :: HS.HashSet (HM.HashMap Int Int)
466
+ -> HM.HashMap Int Int #-}
467
+ {-# SPECIALIZE intersectionC :: S.Set (HM.HashMap Int Int)
468
+ -> HM.HashMap Int Int #-}
469
+
470
+ sizeC :: (Eq k , Hashable k , Functor f ) => f (HM. HashMap k Int ) -> f Int
471
+ sizeC = fmap HM. size
472
+ {-# SPECIALIZE sizeC :: [HM.HashMap Int Int] -> [Int] #-}
473
+ {-# SPECIALIZE sizeC :: V.Vector (HM.HashMap Int Int) -> V.Vector Int #-}
474
+
475
+ sizeHS :: HS. HashSet (HM. HashMap Int Int ) -> HS. HashSet Int
476
+ sizeHS = HS. map HM. size
477
+
478
+ sizeS :: S. Set (HM. HashMap Int Int ) -> S. Set Int
479
+ sizeS = S. map HM. size
313
480
------------------------------------------------------------------------
314
481
-- * Map
315
482
0 commit comments