haskell-unordered-containers / unordered-containers

Efficient hashing-based container types
BSD 3-Clause "New" or "Revised" License
221 stars 97 forks source link

Small optimization idea for `alter[F]` #457

Open sjakobi opened 2 years ago

sjakobi commented 2 years ago

alter and alterF rely on lookupRecordCollision to gather information about the location of a key in the map. This info is stored in a LookupRes:

https://github.com/haskell-unordered-containers/unordered-containers/blob/8bb958e53cb21cf20894fbfd8fbfa37672879173/Data/HashMap/Internal.hs#L654-L656

I think we could slightly reduce the work that a subsequent insertKeyExists or deleteKeyExists has to perform by enhancing this location information with the sequence of array indices that lead to the relevant Leaf or Collision node:

type IndexPath = Word

data LookupRes a = Absent | Present a !IndexPath !Int

This IndexPath is basically a Hash with the difference that even for BitmapIndexed nodes, the array index can be computed with the simple index function instead of the more involved sparseIndex. We won't even need index and the Shift it requires, though, if we simply right-shift the IndexPath at each step.

I don't expect a large speedup from this, but maybe something like 2, 3%?!

https://github.com/haskell-unordered-containers/unordered-containers/blob/8bb958e53cb21cf20894fbfd8fbfa37672879173/Data/HashMap/Internal.hs#L1385-L1422