From 635276a1ddbc859a3244235e8ddf26edb72e963c Mon Sep 17 00:00:00 2001 From: Kevin Quick Date: Sun, 24 Mar 2024 15:32:58 -0700 Subject: [PATCH] More optimization in BitSet and supporting documentation. --- src/Data/Graph/Haggle/Internal/BitSet.hs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Data/Graph/Haggle/Internal/BitSet.hs b/src/Data/Graph/Haggle/Internal/BitSet.hs index 1b1c393..d782f9a 100644 --- a/src/Data/Graph/Haggle/Internal/BitSet.hs +++ b/src/Data/Graph/Haggle/Internal/BitSet.hs @@ -11,6 +11,21 @@ import Data.Vector.Unboxed.Mutable ( STVector ) import qualified Data.Vector.Unboxed.Mutable as V import Data.Word ( Word64 ) +-- Note that the implementation here assumes thaththe bit numbers are all +-- unsigned. A proper implementation would perhaps use 'Natural' instead of +-- 'Int', but that would require gratuitous fromEnum/toEnum conversions from all +-- the other API's that just use 'Int', which has about a 33% performance impact +-- when measured. +-- +-- The 'setBit' and 'testBit' operations use V.unsafeRead instead of V.read +-- (where the latter is roughly 25% slower) because this is an internal module +-- that is generally always used with a positive 'Int' value, and the value is +-- also checked against 'sz' (which is also probably superfluous). In other +-- words, this module prioritizes performance over robustness and should only be +-- used when the caller can guarantee positive Int values and otherwise good +-- behavior. + + data BitSet s = BS (STVector s Word64) {-# UNPACK #-} !Int bitsPerWord :: Int @@ -33,7 +48,7 @@ setBit (BS v sz) bitIx | otherwise = do let wordIx = bitIx `div` bitsPerWord bitPos = bitIx `mod` bitsPerWord - oldWord <- V.read v wordIx + oldWord <- V.unsafeRead v wordIx let newWord = B.setBit oldWord bitPos V.write v wordIx newWord