@@ -10,8 +10,11 @@ import Data.Hashable (Hashable)
1010import qualified Data.ByteString as BS
1111import qualified "hashmap" Data.HashMap as IHM
1212import qualified Data.HashMap.Strict as HM
13+ import qualified Data.HashSet as HS
1314import qualified Data.IntMap as IM
1415import qualified Data.Map as M
16+ import qualified Data.Set as S
17+ import qualified Data.Vector as V
1518import Data.List (foldl' )
1619import Data.Maybe (fromMaybe )
1720import GHC.Generics (Generic )
@@ -36,6 +39,8 @@ instance NFData B where
3639data Env = Env {
3740 n :: ! Int ,
3841
42+ csz :: ! Int , -- container size
43+
3944 elems :: ! [(String , Int )],
4045 keys :: ! [String ],
4146 elemsBS :: ! [(BS. ByteString , Int )],
@@ -48,6 +53,11 @@ data Env = Env {
4853 keysBS' :: ! [BS. ByteString ],
4954 keysI' :: ! [Int ],
5055
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+
5161 keysDup :: ! [String ],
5262 keysDupBS :: ! [BS. ByteString ],
5363 keysDupI :: ! [Int ],
@@ -72,6 +82,20 @@ setupEnv :: IO Env
7282setupEnv = do
7383 let n = 2 ^ (12 :: Int )
7484
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+
7599 elems = zip keys [1 .. n]
76100 keys = US. rnd 8 n
77101 elemsBS = zip keysBS [1 .. n]
@@ -84,6 +108,11 @@ setupEnv = do
84108 keysBS' = UBS. rnd' 8 n
85109 keysI' = UI. rnd' (n+ n) n
86110
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+
87116 keysDup = US. rnd 2 n
88117 keysDupBS = UBS. rnd 2 n
89118 keysDupI = UI. rnd (n`div` 4 ) n
@@ -228,6 +257,57 @@ main = do
228257 , bench " Int" $ whnf (delete keysI') hmi
229258 ]
230259
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 " 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+
231311 -- Combine
232312 , bench " union" $ whnf (HM. union hmi) hmi2
233313
@@ -292,6 +372,18 @@ lookup xs m = foldl' (\z k -> fromMaybe z (HM.lookup k m)) 0 xs
292372{-# SPECIALIZE lookup :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
293373 -> Int #-}
294374
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+
295387insert :: (Eq k , Hashable k ) => [(k , Int )] -> HM. HashMap k Int
296388 -> HM. HashMap k Int
297389insert 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
302394{-# SPECIALIZE insert :: [(BS.ByteString, Int)] -> HM.HashMap BS.ByteString Int
303395 -> HM.HashMap BS.ByteString Int #-}
304396
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+
305412delete :: (Eq k , Hashable k ) => [k ] -> HM. HashMap k Int -> HM. HashMap k Int
306413delete xs m0 = foldl' (\ m k -> HM. delete k m) m0 xs
307414{-# 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
310417{-# SPECIALIZE delete :: [BS.ByteString] -> HM.HashMap BS.ByteString Int
311418 -> HM.HashMap BS.ByteString Int #-}
312419
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
313480------------------------------------------------------------------------
314481-- * Map
315482
0 commit comments