Skip to content

Commit d2093d3

Browse files
committed
Add note explaining this optimisation
1 parent 7e1b4f4 commit d2093d3

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

containers/src/Data/Map/Internal.hs

+18-2
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
-- [Note: Using INLINABLE]
8484
-- ~~~~~~~~~~~~~~~~~~~~~~~
8585
-- It is crucial to the performance that the functions specialize on the Ord
86-
-- type when possible. GHC 7.0 and higher does this by itself when it sees th
86+
-- type when possible. GHC 7.0 and higher does this by itself when it sees the
8787
-- unfolding of a function -- that is why all public functions are marked
8888
-- INLINABLE (that exposes the unfolding).
8989

@@ -116,7 +116,7 @@
116116
-- floats out of its enclosing function and then it heap-allocates the
117117
-- dictionary and the argument. Maybe it floats out too late and strictness
118118
-- analyzer cannot see that these could be passed on stack.
119-
--
119+
120120

121121
-- [Note: Order of constructors]
122122
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -127,6 +127,22 @@
127127
-- On GHC 7.0, reordering constructors from Tip | Bin to Bin | Tip
128128
-- improves the benchmark by up to 10% on x86.
129129

130+
131+
-- [Note: Matching on Leafy Nodes]
132+
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133+
-- In a balanced tree, at least two-thirds of Tip constructors are siblings
134+
-- of another Tip constructor. The parents of these cases can be quickly
135+
-- identified as the size value packed into their Bin constructors will equal
136+
-- 1. By specializing recursive functions which visit the whole tree to
137+
-- recognize this scenario, we can omit unnecessary function calls that would
138+
-- go on to match these Tip constructors but otherwise perform no useful work.
139+
-- This optimization can lead to performance improvements of approximately
140+
-- 30% to 35% for foldMap and foldl', and around 20% for mapMaybe.
141+
--
142+
-- Alternatives, like matching on the Tip constructors directly, or also
143+
-- trying to optimise cases where only one side a Tip are slower in practice.
144+
145+
130146
module Data.Map.Internal (
131147
-- * Map type
132148
Map(..) -- instance Eq,Show,Read

0 commit comments

Comments
 (0)