Experiences in converting Okasaki's ML to F# for PairingHeap: the mergePairs algorithm (6 lines of code in F#) decomposes a PairingHeap, but a direct translation from ML to F# is not tail recursive.
Changing the algorithm to CPS makes it tail recursive, and my first thought was this will be perfect for the ofSeq type member. (I took an educated guess that it should be O(log n).) But no...a simple Seq.fold (which is clearly O(n)) performed as well or better than CPS mergPairs:
loading 100,000 elements from array, times in milliseconds, first time CPS, second Seq.fold
ascending integer 25.8 vs 23.7
random integer 25.3 vs 23.3
ascending string 23.3 vs 18.8
random string 28.3 vs 18.6
...and non-CPS mergePairs does stackoverflow at 100,000 elements.
This is bad news, since the the algorithm is central to the very useful tail and uncons members. As it turns out no test case I developed iterated enough times through the algorithm to actually stackoverflow (testing PairingHeaps of up to 10^6 elements), so I kept the non-CPS version of the algorithm, which is clearly faster than the CPS version:
taking 100,000 element PairingHeap and decomposing by tail, tail, tail... until empty
order refers to order of array from which heap was originally built
first number is CPS, second is non-CPS number
ascending integer 15.3 vs 5.2
random integer 196.6 vs 185.3
ascending string 24.8 vs 7.4
random string 201.6 vs 185.4
The most recent implementation in FSharpx uses the fast (non-CPS) algorithms.