Added more efficient unionWith, eliminate transformation Map to List in Foldable{WithIndex} instances.#60
Conversation
…List` in `Foldable{WithIndex}` instances
JordanMartinez
left a comment
There was a problem hiding this comment.
Could you check what the benchmarks are if the Foldable instances are updated?
|
With the |
JordanMartinez
left a comment
There was a problem hiding this comment.
Thanks @xgrommx.
Would you mind pushing a changelog entry stating that the speed was improved?
| instance foldableMap :: Foldable (Map k) where | ||
| foldl f z m = foldl f z (values m) | ||
| foldr f z m = foldr f z (values m) | ||
| foldMap f m = foldMap f (values m) |
There was a problem hiding this comment.
Should we implement values in terms of foldr? Seems like values being accidentally quadratic is a huge problem.
There was a problem hiding this comment.
He means the values function. Since it produces a List, and each list part is concatenated via <>, which traverses over the list on the left side again (e.g. 1 : 2 : 3 : Nil <> 4 : Nil), then there's room for optimization here.
There was a problem hiding this comment.
In other words, rather than building multiple lists that get appended together, which requires iterating through list parts a second time, we could just build the final list in one go, no traversals needed:
values :: forall k v. Map k v -> List v
values Leaf = Nil
-values (Two left _ v right) = values left <> pure v <> values right
+values (Two left _ v right) = foldr Cons (Cons v (foldr Cons Nil right)) left
-values (Three left _ v1 mid _ v2 right) =
- values left <> pure v1 <> values mid <> pure v2 <> values right
+values (Three left _ v1 mid _ v2 right) =
+ foldr Cons (Cons v1 (foldr Cons (Cons v2 (foldr Cons Nil right) mid))) leftThere was a problem hiding this comment.
Ha! I'm dumb. Actually, values is just foldr Cons Nil.
values :: forall k v. Map k v -> List v
values = foldr Cons Nil
There was a problem hiding this comment.
How do you like them apples?
Map
===
values
---------------
Map2a0bff.values: big map (1000000)
mean = 2.89 s
stddev = 302.43 ms
min = 2.52 s
max = 3.43 s
M.values: big map (1000000)
mean = 278.44 ms
stddev = 4.57 ms
min = 271.75 ms
max = 287.72 ms
|
This is really great work! Thanks! |
thomashoneyman
left a comment
There was a problem hiding this comment.
Fantastic work! Thank you!
Here benchmark results