@@ -11,8 +11,11 @@ import Data.Hashable (Hashable, hash)
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
@@ -273,6 +302,51 @@ main = do
273
302
, bench " Int" $ whnf (alterFDelete keysI') hmi
274
303
]
275
304
305
+ , bgroup " containerized"
306
+ [ bgroup " lookup"
307
+ [ bench " List" $ nf (lookupC keysI) listOfHMs
308
+ , bench " Vector" $ nf (lookupC keysI) vecOfHMs
309
+ , bench " HashSet" $ nf (lookupHS keysI) hsetOfHMs
310
+ , bench " Set" $ nf (lookupS keysI) setOfHMs
311
+ ]
312
+ , bgroup " insert"
313
+ [ bench " List" $ nf (insertC elemsI) listOfHMs
314
+ , bench " Vector" $ nf (insertC elemsI) vecOfHMs
315
+ , bench " HashSet" $ nf (insertHS elemsI) hsetOfHMs
316
+ , bench " Set" $ nf (insertS elemsI) setOfHMs
317
+ ]
318
+ , bgroup " delete"
319
+ [ bench " List" $ nf (deleteC keysI) listOfHMs
320
+ , bench " Vector" $ nf (deleteC keysI) vecOfHMs
321
+ , bench " HashSet" $ nf (deleteHS keysI) hsetOfHMs
322
+ , bench " Set" $ nf (deleteS keysI) setOfHMs
323
+ ]
324
+ , bgroup " union"
325
+ [ bench " List" $ whnf unionC listOfHMs
326
+ , bench " Vector" $ whnf unionC vecOfHMs
327
+ , bench " HashSet" $ whnf unionC hsetOfHMs
328
+ , bench " Set" $ whnf unionC setOfHMs
329
+ ]
330
+ , bgroup " map"
331
+ [ bench " List" $ nf (mapC (\ v -> v + 1 )) listOfHMs
332
+ , bench " Vector" $ nf (mapC (\ v -> v + 1 )) vecOfHMs
333
+ , bench " HashSet" $ nf (mapHS (\ v -> v + 1 )) hsetOfHMs
334
+ , bench " Set" $ nf (mapS (\ v -> v + 1 )) setOfHMs
335
+ ]
336
+ , bgroup " intersection"
337
+ [ bench " List" $ whnf intersectionC listOfHMs
338
+ , bench " Vector" $ whnf intersectionC vecOfHMs
339
+ , bench " HashSet" $ whnf intersectionC hsetOfHMs
340
+ , bench " Set" $ whnf intersectionC setOfHMs
341
+ ]
342
+ , bgroup " size"
343
+ [ bench " List" $ nf sizeC listOfHMs
344
+ , bench " Vector" $ nf sizeC vecOfHMs
345
+ , bench " HashSet" $ nf sizeHS hsetOfHMs
346
+ , bench " Set" $ nf sizeS setOfHMs
347
+ ]
348
+ ]
349
+
276
350
-- Combine
277
351
, bench " union" $ whnf (HM. union hmi) hmi2
278
352
@@ -337,6 +411,18 @@ lookup xs m = foldl' (\z k -> fromMaybe z (HM.lookup k m)) 0 xs
337
411
{-# SPECIALIZE lookup :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
338
412
-> Int #-}
339
413
414
+ lookupC :: (Eq k , Hashable k , Traversable f ) => [k ] -> f (HM. HashMap k Int ) -> f Int
415
+ lookupC = fmap . lookup
416
+ {-# SPECIALIZE lookupC :: [Int] -> [HM.HashMap Int Int] -> [Int] #-}
417
+ {-# SPECIALIZE lookupC :: [Int] -> V.Vector (HM.HashMap Int Int)
418
+ -> V.Vector Int #-}
419
+
420
+ lookupHS :: [Int ] -> HS. HashSet (HM. HashMap Int Int ) -> HS. HashSet Int
421
+ lookupHS = HS. map . lookup
422
+
423
+ lookupS :: [Int ] -> S. Set (HM. HashMap Int Int ) -> S. Set Int
424
+ lookupS = S. map . lookup
425
+
340
426
insert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
341
427
-> HM. HashMap k Int
342
428
insert xs m0 = foldl' (\ m (k, v) -> HM. insert k v m) m0 xs
@@ -347,6 +433,21 @@ insert xs m0 = foldl' (\m (k, v) -> HM.insert k v m) m0 xs
347
433
{-# SPECIALIZE insert :: [(BS.ByteString, Int)] -> HM.HashMap BS.ByteString Int
348
434
-> HM.HashMap BS.ByteString Int #-}
349
435
436
+ insertC :: (Eq k , Hashable k , Traversable f ) => [(k , Int )] -> f (HM. HashMap k Int )
437
+ -> f (HM. HashMap k Int )
438
+ insertC l = fmap (insert l)
439
+ {-# SPECIALIZE insertC :: [(Int, Int)] -> [HM.HashMap Int Int]
440
+ -> [HM.HashMap Int Int] #-}
441
+ {-# SPECIALIZE insertC :: [(Int, Int)] -> V.Vector (HM.HashMap Int Int)
442
+ -> V.Vector (HM.HashMap Int Int) #-}
443
+
444
+ insertHS :: [(Int , Int )] -> HS. HashSet (HM. HashMap Int Int )
445
+ -> HS. HashSet (HM. HashMap Int Int )
446
+ insertHS l = HS. map (insert l)
447
+
448
+ insertS :: [(Int , Int )] -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
449
+ insertS l = S. map (insert l)
450
+
350
451
delete :: (Eq k , Hashable k ) => [k ] -> HM. HashMap k Int -> HM. HashMap k Int
351
452
delete xs m0 = foldl' (\ m k -> HM. delete k m) m0 xs
352
453
{-# SPECIALIZE delete :: [Int] -> HM.HashMap Int Int -> HM.HashMap Int Int #-}
@@ -355,6 +456,21 @@ delete xs m0 = foldl' (\m k -> HM.delete k m) m0 xs
355
456
{-# SPECIALIZE delete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
356
457
-> HM.HashMap BS.ByteString Int #-}
357
458
459
+ deleteC :: (Eq k , Hashable k , Functor f ) => [k ] -> f (HM. HashMap k Int )
460
+ -> f (HM. HashMap k Int )
461
+ deleteC = fmap . delete
462
+ {-# SPECIALIZE deleteC :: [Int] -> [HM.HashMap Int Int]
463
+ -> [HM.HashMap Int Int] #-}
464
+ {-# SPECIALIZE deleteC :: [Int] -> V.Vector (HM.HashMap Int Int)
465
+ -> V.Vector (HM.HashMap Int Int) #-}
466
+
467
+ deleteHS :: [Int ] -> HS. HashSet (HM. HashMap Int Int )
468
+ -> HS. HashSet (HM. HashMap Int Int )
469
+ deleteHS = HS. map . delete
470
+
471
+ deleteS :: [Int ] -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
472
+ deleteS = S. map . delete
473
+
358
474
alterInsert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
359
475
-> HM. HashMap k Int
360
476
alterInsert xs m0 =
@@ -399,6 +515,52 @@ alterFDelete xs m0 =
399
515
{-# SPECIALIZE alterFDelete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
400
516
-> HM.HashMap BS.ByteString Int #-}
401
517
518
+ unionC :: (Eq k , Hashable k , Foldable f ) => f (HM. HashMap k Int )
519
+ -> HM. HashMap k Int
520
+ unionC = foldl' HM. union mempty
521
+ {-# SPECIALIZE unionC :: [HM.HashMap Int Int] -> HM.HashMap Int Int #-}
522
+ {-# SPECIALIZE unionC :: V.Vector (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
523
+ {-# SPECIALIZE unionC :: HS.HashSet (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
524
+ {-# SPECIALIZE unionC :: S.Set (HM.HashMap Int Int) -> HM.HashMap Int Int #-}
525
+
526
+ mapC :: (Eq k , Hashable k , Functor f ) => (Int -> Int ) -> f (HM. HashMap k Int )
527
+ -> f (HM. HashMap k Int )
528
+ mapC f = fmap (HM. map f)
529
+ {-# SPECIALIZE mapC :: (Int -> Int) -> [HM.HashMap Int Int]
530
+ -> [HM.HashMap Int Int] #-}
531
+ {-# SPECIALIZE mapC :: (Int -> Int) -> V.Vector (HM.HashMap Int Int)
532
+ -> V.Vector (HM.HashMap Int Int) #-}
533
+
534
+ mapHS :: (Int -> Int ) -> HS. HashSet (HM. HashMap Int Int )
535
+ -> HS. HashSet (HM. HashMap Int Int )
536
+ mapHS f = HS. map (HM. map f)
537
+
538
+ mapS :: (Int -> Int ) -> S. Set (HM. HashMap Int Int ) -> S. Set (HM. HashMap Int Int )
539
+ mapS f = S. map (HM. map f)
540
+
541
+ intersectionC :: (Eq k , Hashable k , Foldable f ) => f (HM. HashMap k Int )
542
+ -> HM. HashMap k Int
543
+ intersectionC = foldl' HM. intersection mempty
544
+ {-# SPECIALIZE intersectionC :: [HM.HashMap Int Int]
545
+ -> HM.HashMap Int Int #-}
546
+ {-# SPECIALIZE intersectionC :: V.Vector (HM.HashMap Int Int)
547
+ -> HM.HashMap Int Int #-}
548
+ {-# SPECIALIZE intersectionC :: HS.HashSet (HM.HashMap Int Int)
549
+ -> HM.HashMap Int Int #-}
550
+ {-# SPECIALIZE intersectionC :: S.Set (HM.HashMap Int Int)
551
+ -> HM.HashMap Int Int #-}
552
+
553
+ sizeC :: (Eq k , Hashable k , Functor f ) => f (HM. HashMap k Int ) -> f Int
554
+ sizeC = fmap HM. size
555
+ {-# SPECIALIZE sizeC :: [HM.HashMap Int Int] -> [Int] #-}
556
+ {-# SPECIALIZE sizeC :: V.Vector (HM.HashMap Int Int) -> V.Vector Int #-}
557
+
558
+ sizeHS :: HS. HashSet (HM. HashMap Int Int ) -> HS. HashSet Int
559
+ sizeHS = HS. map HM. size
560
+
561
+ sizeS :: S. Set (HM. HashMap Int Int ) -> S. Set Int
562
+ sizeS = S. map HM. size
563
+
402
564
------------------------------------------------------------------------
403
565
-- * Map
404
566
0 commit comments