@@ -11,8 +11,11 @@ import Data.Hashable (Hashable, hash)
1111import qualified Data.ByteString as BS
1212import qualified "hashmap" Data.HashMap as IHM
1313import qualified Data.HashMap.Strict as HM
14+ import qualified Data.HashSet as HS
1415import qualified Data.IntMap as IM
1516import qualified Data.Map as M
17+ import qualified Data.Set as S
18+ import qualified Data.Vector as V
1619import Data.List (foldl' )
1720import Data.Maybe (fromMaybe )
1821import GHC.Generics (Generic )
@@ -37,6 +40,8 @@ instance NFData B where
3740data Env = Env {
3841 n :: ! Int ,
3942
43+ csz :: ! Int , -- container size
44+
4045 elems :: ! [(String , Int )],
4146 keys :: ! [String ],
4247 elemsBS :: ! [(BS. ByteString , Int )],
@@ -49,6 +54,11 @@ data Env = Env {
4954 keysBS' :: ! [BS. ByteString ],
5055 keysI' :: ! [Int ],
5156
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+
5262 keysDup :: ! [String ],
5363 keysDupBS :: ! [BS. ByteString ],
5464 keysDupI :: ! [Int ],
@@ -73,6 +83,20 @@ setupEnv :: IO Env
7383setupEnv = do
7484 let n = 2 ^ (12 :: Int )
7585
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+
76100 elems = zip keys [1 .. n]
77101 keys = US. rnd 8 n
78102 elemsBS = zip keysBS [1 .. n]
@@ -85,6 +109,11 @@ setupEnv = do
85109 keysBS' = UBS. rnd' 8 n
86110 keysI' = UI. rnd' (n+ n) n
87111
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+
88117 keysDup = US. rnd 2 n
89118 keysDupBS = UBS. rnd 2 n
90119 keysDupI = UI. rnd (n`div` 4 ) n
@@ -273,6 +302,51 @@ main = do
273302 , bench " Int" $ whnf (alterFDelete keysI') hmi
274303 ]
275304
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+
276350 -- Combine
277351 , bench " union" $ whnf (HM. union hmi) hmi2
278352
@@ -337,6 +411,18 @@ lookup xs m = foldl' (\z k -> fromMaybe z (HM.lookup k m)) 0 xs
337411{-# SPECIALIZE lookup :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
338412 -> Int #-}
339413
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+
340426insert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
341427 -> HM. HashMap k Int
342428insert 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
347433{-# SPECIALIZE insert :: [(BS.ByteString, Int)] -> HM.HashMap BS.ByteString Int
348434 -> HM.HashMap BS.ByteString Int #-}
349435
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+
350451delete :: (Eq k , Hashable k ) => [k ] -> HM. HashMap k Int -> HM. HashMap k Int
351452delete xs m0 = foldl' (\ m k -> HM. delete k m) m0 xs
352453{-# 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
355456{-# SPECIALIZE delete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
356457 -> HM.HashMap BS.ByteString Int #-}
357458
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+
358474alterInsert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
359475 -> HM. HashMap k Int
360476alterInsert xs m0 =
@@ -399,6 +515,52 @@ alterFDelete xs m0 =
399515{-# SPECIALIZE alterFDelete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
400516 -> HM.HashMap BS.ByteString Int #-}
401517
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+
402564------------------------------------------------------------------------
403565-- * Map
404566
0 commit comments