Skip to content

Commit 0d0a9d4

Browse files
authored
Faster hashing for HashMaps (#209)
* Measure performance of hashing a HashMap * Don't use toList' when hashing a HashMap * Bump criterion upper bound
1 parent ae56c6e commit 0d0a9d4

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

Data/HashMap/Base.hs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -461,17 +461,18 @@ instance (Hashable k) => H.Hashable1 (HashMap k) where
461461
#endif
462462

463463
instance (Hashable k, Hashable v) => Hashable (HashMap k v) where
464-
hashWithSalt salt hm = go salt (toList' hm [])
464+
hashWithSalt salt hm = go salt hm
465465
where
466-
go :: Int -> [HashMap k v] -> Int
467-
go s [] = s
468-
go s (Leaf _ l : tl)
469-
= s `hashLeafWithSalt` l `go` tl
466+
go :: Int -> HashMap k v -> Int
467+
go s Empty = s
468+
go s (BitmapIndexed _ a) = A.foldl' go s a
469+
go s (Leaf h (L _ v))
470+
= s `H.hashWithSalt` h `H.hashWithSalt` v
470471
-- For collisions we hashmix hash value
471472
-- and then array of values' hashes sorted
472-
go s (Collision h a : tl)
473-
= (s `H.hashWithSalt` h) `hashCollisionWithSalt` a `go` tl
474-
go s (_ : tl) = s `go` tl
473+
go s (Full a) = A.foldl' go s a
474+
go s (Collision h a)
475+
= (s `H.hashWithSalt` h) `hashCollisionWithSalt` a
475476

476477
hashLeafWithSalt :: Int -> Leaf k v -> Int
477478
hashLeafWithSalt s (L k v) = s `H.hashWithSalt` k `H.hashWithSalt` v

benchmarks/Benchmarks.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Control.DeepSeq.Generics (genericRnf)
77
import Gauge (bench, bgroup, defaultMain, env, nf, whnf)
88
import Data.Bits ((.&.))
99
import Data.Functor.Identity
10-
import Data.Hashable (Hashable)
10+
import Data.Hashable (Hashable, hash)
1111
import qualified Data.ByteString as BS
1212
import qualified "hashmap" Data.HashMap as IHM
1313
import qualified Data.HashMap.Strict as HM
@@ -180,6 +180,10 @@ main = do
180180
[ bench "String" $ whnf IHM.fromList elems
181181
, bench "ByteString" $ whnf IHM.fromList elemsBS
182182
]
183+
, bgroup "hash"
184+
[ bench "String" $ whnf hash hm
185+
, bench "ByteString" $ whnf hash hmbs
186+
]
183187
]
184188

185189
-- ** IntMap

0 commit comments

Comments
 (0)