apple / swift-collections

Commonly used data structures for Swift
Apache License 2.0
3.55k stars 270 forks source link

`Heap.insert(contentsOf:)` is quasilinear instead of linear complexity #325

Closed lorentey closed 5 months ago

lorentey commented 6 months ago

The current implementation of Heap.insert(contentsOf:) simply iterates over newElements, individually inserting them into the heap, one by one.

This can sometimes be quite inefficient, as it has quasilinear O(n * log(n)) complexity. If we have more than a handful of items to insert, it would be better to just append them to the storage array and re-run Floyd's heap construction algorithm on the entire resulting storage, which would take linear O(n) complexity.

Fix insert(contentsOf:) to switch between the naive loop and Floyds, based on some heuristic function defined over the size of the original heap and the length of the appended sequence. A small back-of-the-envelope calculation implies one possible heuristic would be to switch to using Floyd whenever the number of new items k is greater than 2 * (n + k) / log(n + k).

rdar://118373784