1- -- | This file is formatted with https://hackage.haskell.org/package/ormolu
2-
1+ -- This file is formatted with https://hackage.haskell.org/package/ormolu
32{-# LANGUAGE DeriveAnyClass #-}
43{-# LANGUAGE DeriveGeneric #-}
54{-# LANGUAGE NumericUnderscores #-}
3029 [ bFromList,
3130 bLookup,
3231 bInsert,
32+ bUpdate,
33+ bAlter,
3334 bDelete,
3435 bUnion,
3536 bUnions,
@@ -182,6 +183,115 @@ bInsertAbsentKey =
182183 let kvs = take 1000 $ Data.List. cycle $ map (,1 ) $ filter (not . flip HM. member m) ks
183184 return (m, kvs)
184185
186+ bUpdate :: Benchmark
187+ bUpdate =
188+ bgroup
189+ " update (1000x)"
190+ [ bgroup " presentKey" bUpdatePresentKey,
191+ bgroup " absentKey" bUpdateAbsentKey
192+ ]
193+
194+ updateF :: Int -> Maybe Int
195+ updateF x
196+ | intPredicate x = Nothing
197+ | x `mod` 3 == 0 = Just (x + 1 )
198+ | otherwise = Just x
199+
200+ bUpdateAbsentKey :: [Benchmark ]
201+ bUpdateAbsentKey =
202+ [ bgroup' " Bytes" setupBytes b,
203+ bgroup' " Int" setupInts b
204+ ]
205+ where
206+ b s =
207+ bench (show s)
208+ . whnf (\ (m, ks) -> foldl' (\ () k -> HM. update updateF k m `seq` () ) () ks)
209+ setupBytes size gen = do
210+ m <- genBytesMap size gen
211+ ks <- genNBytes 2000 bytesLength gen
212+ let ks' = take 1000 $ Data.List. cycle $ filter (not . flip HM. member m) ks
213+ return (m, ks')
214+ setupInts size gen = do
215+ m <- genIntMap size gen
216+ ks <- genInts 2000 gen
217+ let ks' = take 1000 $ Data.List. cycle $ filter (not . flip HM. member m) ks
218+ return (m, ks')
219+
220+ bUpdatePresentKey :: [Benchmark ]
221+ bUpdatePresentKey =
222+ [ bgroup'WithSizes sizes " Bytes" setupBytes b,
223+ bgroup'WithSizes sizes " Int" setupInts b
224+ ]
225+ where
226+ sizes = filter (/= 0 ) defaultSizes
227+ b s =
228+ bench (show s)
229+ . whnf (\ (m, ks) -> foldl' (\ () k -> HM. update updateF k m `seq` () ) () ks)
230+ toKs = take 1000 . Data.List. cycle . HM. keys
231+ setupBytes size gen = do
232+ m <- genBytesMap size gen
233+ return (m, toKs m)
234+ setupInts size gen = do
235+ m <- genIntMap size gen
236+ return (m, toKs m)
237+
238+ bAlter :: Benchmark
239+ bAlter =
240+ bgroup
241+ " alter (1000x)"
242+ [ bgroup " presentKey" bAlterPresentKey,
243+ bgroup " absentKey" bAlterAbsentKey
244+ ]
245+
246+ alterF' :: (Hashable k ) => k -> Maybe Int -> Maybe Int
247+ alterF' k Nothing
248+ | intPredicate (hash k) = Nothing
249+ | otherwise = Just (hash k)
250+ alterF' k (Just v)
251+ | odd n = Nothing
252+ | intPredicate n = Just (n + 1 )
253+ | otherwise = Just v
254+ where
255+ n = hash k + v
256+
257+ bAlterAbsentKey :: [Benchmark ]
258+ bAlterAbsentKey =
259+ [ bgroup' " Bytes" setupBytes b,
260+ bgroup' " Int" setupInts b
261+ ]
262+ where
263+ b s =
264+ bench (show s)
265+ . whnf (\ (m, ks) -> foldl' (\ () k -> HM. alter (alterF' k) k m `seq` () ) () ks)
266+ setupBytes size gen = do
267+ m <- genBytesMap size gen
268+ ks <- genNBytes 2000 bytesLength gen
269+ let ks' = take 1000 $ Data.List. cycle $ filter (not . flip HM. member m) ks
270+ return (m, ks')
271+ setupInts size gen = do
272+ m <- genIntMap size gen
273+ ks <- genInts 2000 gen
274+ let ks' = take 1000 $ Data.List. cycle $ filter (not . flip HM. member m) ks
275+ return (m, ks')
276+
277+ bAlterPresentKey :: [Benchmark ]
278+ bAlterPresentKey =
279+ [ bgroup'WithSizes sizes " Bytes" setupBytes b,
280+ bgroup'WithSizes sizes " Int" setupInts b
281+ ]
282+ where
283+ sizes = filter (/= 0 ) defaultSizes
284+ b s =
285+ bench (show s)
286+ . whnf (\ (m, ks) -> foldl' (\ () k -> HM. alter (alterF' k) k m `seq` () ) () ks)
287+ toKs = take 1000 . Data.List. cycle . HM. keys
288+ setupBytes size gen = do
289+ m <- genBytesMap size gen
290+ return (m, toKs m)
291+ setupInts size gen = do
292+ m <- genIntMap size gen
293+ return (m, toKs m)
294+
185295-- 1000 deletions each, so we get more precise timings
186296bDelete :: Benchmark
187297bDelete =
@@ -266,10 +376,12 @@ bUnionEqual =
266376 b size = bench (show size) . whnf (\ m -> HM. union m m)
267377
268378bUnions :: Benchmark
269- bUnions = bgroup " unions"
270- [ bgroup'WithSizes sizes " Bytes" setupBytes b,
271- bgroup'WithSizes sizes " Int" setupInts b
272- ]
379+ bUnions =
380+ bgroup
381+ " unions"
382+ [ bgroup'WithSizes sizes " Bytes" setupBytes b,
383+ bgroup'WithSizes sizes " Int" setupInts b
384+ ]
273385 where
274386 sizes = filter (>= 10 ) defaultSizes
275387 b size = bench (show size) . whnf (\ ms -> HM. unions ms)
@@ -432,7 +544,7 @@ env' setup b size =
432544-- Generators
433545
434546keysToMap :: (Hashable k ) => [k ] -> HashMap k Int
435- keysToMap = HM. fromList . map (, 1 )
547+ keysToMap = HM. fromList . map (\ k -> (k, hashWithSalt 123 k) )
436548
437549genInts ::
438550 (StatefulGen g m ) =>
@@ -482,7 +594,7 @@ genIntMapsDisjoint ::
482594 Int -> g -> m (HashMap Int Int , HashMap Int Int )
483595genIntMapsDisjoint s gen = do
484596 ints <- genInts s gen
485- let (trues, falses) = Data.List. partition ( flip testBit ( 31 :: Int )) ints
597+ let (trues, falses) = Data.List. partition intPredicate ints
486598 return (keysToMap trues, keysToMap falses)
487599
488600genBytesMapsDisjoint ::
@@ -491,3 +603,6 @@ genBytesMapsDisjoint ::
491603genBytesMapsDisjoint s gen = do
492604 (trues, falses) <- Key.Bytes. genDisjoint s bytesLength gen
493605 return (keysToMap trues, keysToMap falses)
606+
607+ intPredicate :: Int -> Bool
608+ intPredicate n = testBit n 31
0 commit comments