EventLoop: store Timers in min Pairing Heap #15206
Draft
+450
−156
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Replaces the
Deque
used in #14996 for a min Pairing Heap which is a kind of Mergeable Heap and is one of the best performing heap in practical tests when arbitrary deletions are required (think cancelling a timeout), otherwise a D-ary Heap (e.g. 4-heap) will usually perform better. See the A Nearly-Tight Analysis of Multipass Pairing Heaps paper or the Wikipedia page for more details.The implementation itself is based on the Pairing Heaps: Experiments and Analysis paper, and merely implements a recursive twopass algorithm (the auxiliary twopass might perform even better). The
Crystal::PointerPairingList(T)
type is generic and relies on intrusive nodes (the links are intoT
) to avoid extra allocations for the nodes (same asCrystal::PointerLinkedList(T)
). It also requires aT#heap_compare
method, so we can use the same type for a min or max heap, or to build a more complex comparison.Note: I also tried a 4-heap, and while it performs very well and only needs a flat array, the arbitrary deletion (e.g. cancelling timeout) needs a linear scan and its performance quickly plummets, even at low occupancy, and becomes painfully slow at higher occupancy (tens of microseconds on each delete, while the pairing heap does it in tens of nanoseconds).
Follow up to #14996
Builds on top of #15205, you should open the last commit for just the pairing heap.