@@ -11,8 +11,11 @@ import Data.Hashable (Hashable)
11
11
import qualified Data.ByteString as BS
12
12
import qualified "hashmap" Data.HashMap as IHM
13
13
import qualified Data.HashMap.Strict as HM
14
+ import qualified Data.HashSet as HS
14
15
import qualified Data.IntMap as IM
15
16
import qualified Data.Map as M
17
+ import qualified Data.Set as S
18
+ import qualified Data.Vector as V
16
19
import Data.List (foldl' )
17
20
import Data.Maybe (fromMaybe )
18
21
import GHC.Generics (Generic )
@@ -37,6 +40,8 @@ instance NFData B where
37
40
data Env = Env {
38
41
n :: ! Int ,
39
42
43
+ csz :: ! Int , -- container size
44
+
40
45
elems :: ! [(String , Int )],
41
46
keys :: ! [String ],
42
47
elemsBS :: ! [(BS. ByteString , Int )],
@@ -49,6 +54,11 @@ data Env = Env {
49
54
keysBS' :: ! [BS. ByteString ],
50
55
keysI' :: ! [Int ],
51
56
57
+ listOfHMs :: ! [HM. HashMap Int Int ],
58
+ vecOfHMs :: ! (V. Vector (HM. HashMap Int Int )),
59
+ hsetOfHMs :: ! (HS. HashSet (HM. HashMap Int Int )),
60
+ setOfHMs :: ! (S. Set (HM. HashMap Int Int )),
61
+
52
62
keysDup :: ! [String ],
53
63
keysDupBS :: ! [BS. ByteString ],
54
64
keysDupI :: ! [Int ],
@@ -73,6 +83,20 @@ setupEnv :: IO Env
73
83
setupEnv = do
74
84
let n = 2 ^ (12 :: Int )
75
85
86
+ -- When building a container of hashmaps, 'cn' will be the size of each.
87
+ cn = n `div` 16
88
+ -- 'csz' is the size of the container of hashmaps.
89
+ csz = 2 ^ (7 :: Int )
90
+
91
+ values = [1 .. csz* cn]
92
+
93
+ chop _ [] = []
94
+ chop k l =
95
+ let (taken, left) = splitAt k l
96
+ in taken : chop k left
97
+
98
+ vals = chop cn values
99
+
76
100
elems = zip keys [1 .. n]
77
101
keys = US. rnd 8 n
78
102
elemsBS = zip keysBS [1 .. n]
@@ -85,6 +109,11 @@ setupEnv = do
85
109
keysBS' = UBS. rnd' 8 n
86
110
keysI' = UI. rnd' (n+ n) n
87
111
112
+ listOfHMs = zipWith (\ x y -> HM. fromList (zip x y)) (repeat keysI) vals
113
+ vecOfHMs = V. fromList listOfHMs
114
+ hsetOfHMs = HS. fromList listOfHMs
115
+ setOfHMs = S. fromList listOfHMs
116
+
88
117
keysDup = US. rnd 2 n
89
118
keysDupBS = UBS. rnd 2 n
90
119
keysDupI = UI. rnd (n`div` 4 ) n
@@ -269,6 +298,51 @@ main = do
269
298
, bench " Int" $ whnf (alterFDelete keysI') hmi
270
299
]
271
300
301
+ , bgroup " containerized"
302
+ [ bgroup " lookup"
303
+ [ bench " List" $ nf (lookupC keysI) listOfHMs
304
+ , bench " Vector" $ nf (lookupC keysI) vecOfHMs
305
+ , bench " HashSet" $ nf (lookupHS keysI) hsetOfHMs
306
+ , bench " Set" $ nf (lookupS keysI) setOfHMs
307
+ ]
308
+ , bgroup " insert"
309
+ [ bench " List" $ nf (insertC elemsI) listOfHMs
310
+ , bench " Vector" $ nf (insertC elemsI) vecOfHMs
311
+ , bench " HashSet" $ nf (insertHS elemsI) hsetOfHMs
312
+ , bench " Set" $ nf (insertS elemsI) setOfHMs
313
+ ]
314
+ , bgroup " delete"
315
+ [ bench " List" $ nf (deleteC keysI) listOfHMs
316
+ , bench " Vector" $ nf (deleteC keysI) vecOfHMs
317
+ , bench " HashSet" $ nf (deleteHS keysI) hsetOfHMs
318
+ , bench " Set" $ nf (deleteS keysI) setOfHMs
319
+ ]
320
+ , bgroup " union"
321
+ [ bench " List" $ whnf unionC listOfHMs
322
+ , bench " Vector" $ whnf unionC vecOfHMs
323
+ , bench " HashSet" $ whnf unionC hsetOfHMs
324
+ , bench " Set" $ whnf unionC setOfHMs
325
+ ]
326
+ , bgroup " map"
327
+ [ bench " List" $ nf (mapC (\ v -> v + 1 )) listOfHMs
328
+ , bench " Vector" $ nf (mapC (\ v -> v + 1 )) vecOfHMs
329
+ , bench " HashSet" $ nf (mapHS (\ v -> v + 1 )) hsetOfHMs
330
+ , bench " Set" $ nf (mapS (\ v -> v + 1 )) setOfHMs
331
+ ]
332
+ , bgroup " intersection"
333
+ [ bench " List" $ whnf intersectionC listOfHMs
334
+ , bench " Vector" $ whnf intersectionC vecOfHMs
335
+ , bench " HashSet" $ whnf intersectionC hsetOfHMs
336
+ , bench " Set" $ whnf intersectionC setOfHMs
337
+ ]
338
+ , bgroup " size"
339
+ [ bench " List" $ nf sizeC listOfHMs
340
+ , bench " Vector" $ nf sizeC vecOfHMs
341
+ , bench " HashSet" $ nf sizeHS hsetOfHMs
342
+ , bench " Set" $ nf sizeS setOfHMs
343
+ ]
344
+ ]
345
+
272
346
-- Combine
273
347
, bench " union" $ whnf (HM. union hmi) hmi2
274
348
@@ -333,6 +407,18 @@ lookup xs m = foldl' (\z k -> fromMaybe z (HM.lookup k m)) 0 xs
333
407
{-# SPECIALIZE lookup :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
334
408
-> Int #-}
335
409
410
+ lookupC :: (Eq k , Hashable k , Traversable f ) => [k ] -> f (HM. HashMap k Int ) -> f Int
411
+ lookupC = fmap . lookup
412
+ {-# SPECIALIZE lookupC :: [Int] -> [HM.HashMap Int Int] -> [Int] #-}
413
+ {-# SPECIALIZE lookupC :: [Int] -> V.Vector (HM.HashMap Int Int)
414
+ -> V.Vector Int #-}
415
+
416
+ lookupHS :: [Int ] -> HS. HashSet (HM. HashMap Int Int ) -> HS. HashSet Int
417
+ lookupHS = HS. map . lookup
418
+
419
+ lookupS :: [Int ] -> S. Set (HM. HashMap Int Int ) -> S. Set Int
420
+ lookupS = S. map . lookup
421
+
336
422
insert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
337
423
-> HM. HashMap k Int
338
424
insert xs m0 = foldl' (\ m (k, v) -> HM. insert k v m) m0 xs
@@ -343,6 +429,21 @@ insert xs m0 = foldl' (\m (k, v) -> HM.insert k v m) m0 xs
343
429
{-# SPECIALIZE insert :: [(BS.ByteString, Int)] -> HM.HashMap BS.ByteString Int
344
430
-> HM.HashMap BS.ByteString Int #-}
345
431
432
+ insertC :: (Eq k , Hashable k , Traversable f ) => [(k , Int )] -> f (HM. HashMap k Int )
433
+ -> f (HM. HashMap k Int )
434
+ insertC l = fmap (insert l)
435
+ {-# SPECIALIZE insertC :: [(Int, Int)] -> [HM.HashMap Int Int]
436
+ -> [HM.HashMap Int Int] #-}
437
+ {-# SPECIALIZE insertC :: [(Int, Int)] -> V.Vector (HM.HashMap Int Int)
438
+ -> V.Vector (HM.HashMap Int Int) #-}
439
+
440
+ insertHS :: [(Int , Int )] -> HS. HashSet (HM. HashMap Int Int )
441
+ -> HS. HashSet (HM. HashMap Int Int )
442
+ insertHS l = HS. map (insert l)
443
+
444
+ insertS :: [(Int , Int )] -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
445
+ insertS l = S. map (insert l)
446
+
346
447
delete :: (Eq k , Hashable k ) => [k ] -> HM. HashMap k Int -> HM. HashMap k Int
347
448
delete xs m0 = foldl' (\ m k -> HM. delete k m) m0 xs
348
449
{-# SPECIALIZE delete :: [Int] -> HM.HashMap Int Int -> HM.HashMap Int Int #-}
@@ -351,6 +452,21 @@ delete xs m0 = foldl' (\m k -> HM.delete k m) m0 xs
351
452
{-# SPECIALIZE delete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
352
453
-> HM.HashMap BS.ByteString Int #-}
353
454
455
+ deleteC :: (Eq k , Hashable k , Functor f ) => [k ] -> f (HM. HashMap k Int )
456
+ -> f (HM. HashMap k Int )
457
+ deleteC = fmap . delete
458
+ {-# SPECIALIZE deleteC :: [Int] -> [HM.HashMap Int Int]
459
+ -> [HM.HashMap Int Int] #-}
460
+ {-# SPECIALIZE deleteC :: [Int] -> V.Vector (HM.HashMap Int Int)
461
+ -> V.Vector (HM.HashMap Int Int) #-}
462
+
463
+ deleteHS :: [Int ] -> HS. HashSet (HM. HashMap Int Int )
464
+ -> HS. HashSet (HM. HashMap Int Int )
465
+ deleteHS = HS. map . delete
466
+
467
+ deleteS :: [Int ] -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
468
+ deleteS = S. map . delete
469
+
354
470
alterInsert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
355
471
-> HM. HashMap k Int
356
472
alterInsert xs m0 =
@@ -395,6 +511,52 @@ alterFDelete xs m0 =
395
511
{-# SPECIALIZE alterFDelete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
396
512
-> HM.HashMap BS.ByteString Int #-}
397
513
514
+ unionC :: (Eq k , Hashable k , Foldable f ) => f (HM. HashMap k Int )
515
+ -> HM. HashMap k Int
516
+ unionC = foldl' HM. union mempty
517
+ {-# SPECIALIZE unionC :: [HM.HashMap Int Int] -> HM.HashMap Int Int #-}
518
+ {-# SPECIALIZE unionC :: V.Vector (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
519
+ {-# SPECIALIZE unionC :: HS.HashSet (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
520
+ {-# SPECIALIZE unionC :: S.Set (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
521
+
522
+ mapC :: (Eq k , Hashable k , Functor f ) => (Int -> Int ) -> f (HM. HashMap k Int )
523
+ -> f (HM. HashMap k Int )
524
+ mapC f = fmap (HM. map f)
525
+ {-# SPECIALIZE mapC :: (Int -> Int) -> [HM.HashMap Int Int]
526
+ -> [HM.HashMap Int Int] #-}
527
+ {-# SPECIALIZE mapC :: (Int -> Int) -> V.Vector (HM.HashMap Int Int)
528
+ -> V.Vector (HM.HashMap Int Int) #-}
529
+
530
+ mapHS :: (Int -> Int ) -> HS. HashSet (HM. HashMap Int Int )
531
+ -> HS. HashSet (HM. HashMap Int Int )
532
+ mapHS f = HS. map (HM. map f)
533
+
534
+ mapS :: (Int -> Int ) -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
535
+ mapS f = S. map (HM. map f)
536
+
537
+ intersectionC :: (Eq k , Hashable k , Foldable f ) => f (HM. HashMap k Int )
538
+ -> HM. HashMap k Int
539
+ intersectionC = foldl' HM. intersection mempty
540
+ {-# SPECIALIZE intersectionC :: [HM.HashMap Int Int]
541
+ -> HM.HashMap Int Int #-}
542
+ {-# SPECIALIZE intersectionC :: V.Vector (HM.HashMap Int Int)
543
+ -> HM.HashMap Int Int #-}
544
+ {-# SPECIALIZE intersectionC :: HS.HashSet (HM.HashMap Int Int)
545
+ -> HM.HashMap Int Int #-}
546
+ {-# SPECIALIZE intersectionC :: S.Set (HM.HashMap Int Int)
547
+ -> HM.HashMap Int Int #-}
548
+
549
+ sizeC :: (Eq k , Hashable k , Functor f ) => f (HM. HashMap k Int ) -> f Int
550
+ sizeC = fmap HM. size
551
+ {-# SPECIALIZE sizeC :: [HM.HashMap Int Int] -> [Int] #-}
552
+ {-# SPECIALIZE sizeC :: V.Vector (HM.HashMap Int Int) -> V.Vector Int #-}
553
+
554
+ sizeHS :: HS. HashSet (HM. HashMap Int Int ) -> HS. HashSet Int
555
+ sizeHS = HS. map HM. size
556
+
557
+ sizeS :: S. Set (HM. HashMap Int Int ) -> S. Set Int
558
+ sizeS = S. map HM. size
559
+
398
560
------------------------------------------------------------------------
399
561
-- * Map
400
562
0 commit comments