Skip to content

Commit f149d50

Browse files
Use a single fold for difference (#64)
* Use a single fold for difference * Add changelog entry
1 parent 9826b76 commit f149d50

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ New features:
1111
Bugfixes:
1212

1313
Other improvements:
14+
- Speed up `difference` by using 1 fold instead of 2 (#64 by @JordanMartinez)
1415

1516
## [v3.0.0](https://github.com/purescript/purescript-ordered-collections/releases/tag/v3.0.0) - 2022-04-27
1617

bench/Bench/Data/Map.purs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ benchMap = do
4848
log "---------------"
4949
benchKeys
5050

51+
log "difference"
52+
log "---------------"
53+
benchDifference
54+
5155
where
5256

5357
benchUnion = do
@@ -61,7 +65,7 @@ benchMap = do
6165
bigMap2' = M.fromFoldable $ natPairs2
6266
size = Map2a0bff.size bigMap
6367
size' = M.size bigMap'
64-
68+
6569
log $ "Map2a0bff.union: big map (" <> show size <> ")"
6670
benchWith 10 \_ -> Map2a0bff.union bigMap bigMap2
6771

@@ -170,3 +174,32 @@ benchMap = do
170174

171175
log $ "fromFoldable (" <> show (L.length natPairs) <> ")"
172176
benchWith 10 \_ -> M.fromFoldable natPairs
177+
178+
benchDifference = do
179+
let nats = L.range 0 999999
180+
natPairs = (flip Tuple) unit <$> nats
181+
singletonMap = M.singleton 0 unit
182+
smallMap = Map2a0bff.fromFoldable $ L.take 100 natPairs
183+
smallMap' = M.fromFoldable $ L.take 100 natPairs
184+
midMap = Map2a0bff.fromFoldable $ L.take 10000 natPairs
185+
midMap' = M.fromFoldable $ L.take 10000 natPairs
186+
bigMap = Map2a0bff.fromFoldable $ natPairs
187+
bigMap' = M.fromFoldable $ natPairs
188+
189+
log $ "Map2a0bff.difference: small map (" <> show (Map2a0bff.size smallMap) <> ")"
190+
bench \_ -> Map2a0bff.difference smallMap midMap
191+
192+
log $ "M.difference: small map (" <> show (M.size smallMap') <> ")"
193+
bench \_ -> M.difference smallMap' midMap'
194+
195+
log $ "Map2a0bff.difference: midsize map (" <> show (Map2a0bff.size midMap) <> ")"
196+
benchWith 100 \_ -> Map2a0bff.difference midMap midMap
197+
198+
log $ "M.difference: midsize map (" <> show (M.size midMap') <> ")"
199+
benchWith 100 \_ -> M.difference midMap' midMap'
200+
201+
log $ "Map2a0bff.difference: big map (" <> show (Map2a0bff.size bigMap) <> ")"
202+
benchWith 10 \_ -> Map2a0bff.difference bigMap midMap
203+
204+
log $ "M.difference: big map (" <> show (M.size bigMap') <> ")"
205+
benchWith 10 \_ -> M.difference bigMap' midMap'

src/Data/Map/Internal.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ intersection = intersectionWith const
694694
-- | Difference of two maps. Return elements of the first map where
695695
-- | the keys do not exist in the second map.
696696
difference :: forall k v w. Ord k => Map k v -> Map k w -> Map k v
697-
difference m1 m2 = foldl (flip delete) m1 (keys m2)
697+
difference m1 m2 = foldlWithIndex (\k m _ -> delete k m) m1 m2
698698

699699
-- | Test whether one map contains all of the keys and values contained in another map
700700
isSubmap :: forall k v. Ord k => Eq v => Map k v -> Map k v -> Boolean

0 commit comments

Comments
 (0)