-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FindIndices optimized using findIndex and inlining #270
Conversation
Impressive! Could you please add benchmarks? |
Could we possibly also add rewrite rules? {-# RULES
"ByteString specialise findIndex (x ==)" forall x. findIndex (x ==) = elemIndex x
"ByteString specialise findIndex (== x)" forall x. findIndex (== x) = elemIndex x
"ByteString specialise findIndices (x ==)" forall x. findIndices (x ==) = elemIndices x
"ByteString specialise findIndices (== x)" forall x. findIndices (== x) = elemIndices x
#-} This would fix haskell-streaming/streaming-bytestring#15 for free. |
I haven't really explored the RULES pragma deeply enough to know for certain, but I am reasonably sure that we would have to be careful to specify an appropriate phase number so that the rule can fire before I did end up benchmarking the relative performance of findIndex and findIndices before and after the changes (both the reimplementation and the inlining, as separate comparisons), but any benchmark I write will only reflect the current relative performance, and won't indicate a diachronic benchmark of the previous implementation of findIndices against the reimplemented one. I can still include it, but it is perhaps only useful for posterity if the implementation changes again. If you let me know exactly what kind of benchmark you had in mind, I can try to include something appropriately illustrative of the comparison you wanted to make. |
Yes, you can use -- For Data.ByteString.Char8
{-# INLINE [1] findIndices #-}
{-# RULES "findIndices (== x)" forall x. findIndices (`eqChar` x) = elemIndices x #-}
-- For Data.ByteString
{-# INLINE [1] findIndices #-}
{-# RULES "findIndices (== x)" forall x. findIndices (`eqWord8` x) = elemIndices x #-} Cf. Lines 879 to 881 in 155bf8a
bytestring/Data/ByteString/Char8.hs Lines 538 to 540 in 155bf8a
Just add a single benchmark for |
Reimplements findIndices to iteratively call findIndex, which yields an approximate 2x improvement over original implementation for a simple equality predicate Adds inline pragma for findIndices, which yields an approximate 10x improvement for a simple equality predicate Adds rewrite rules that optimize calls of `findIndex (==x)` with `elemIndex x` and `findIndices (==x)`->`elemIndices x` (both left- and right-sections) for Data.ByteString and Data.ByteString.Char8 Adds phase number [1] for inline rules on `findIndex` and `findIndices` to allow said rules to fire properly
Thanks, @archaephyrryx! |
Reimplements findIndices to iteratively call findIndex, which
yields an approximate 2x improvement over original implementation
for a simple equality predicate
Adds inline pragma for findIndices, which yields an approximate 10x
improvement for a simple equality predicate
Additionally inlines findIndices functions in
Data.ByteString{.Lazy,}{.Char8,}
resolves #269