Repository navigation
Core implementaiton of List.sortByDescending #20848
Replies: 2 comments
|
Diagnosis is right. The
A version that keeps both properties is project once, then stable sort by key descending: let sortByDescending projection list =
match list with
| [] | [ _ ] -> list
| _ ->
let arr = List.toArray list
let keys = Array.map projection arr
Array.init arr.Length id
|> Array.sortWith (fun i j ->
let c = compare keys.[j] keys.[i]
if c <> 0 then c else compare i j)
|> Array.map (fun i -> arr.[i])
|> List.ofArraySame result as the built-in on my test data, with one projection per element. |
|
A PR with clear benchmarks on CPU + allocations showing evidence for various scenarios including. trivial comparators as well will be accepted 👍 . |
Uh oh!
There was an error while loading. Please reload this page.
The current implementation:
Can be extremely slow if the projection is modestly compute intensive. This is because this implementation will call that projection on (perhaps) O(n log n) pair of elements in the collection. I think this might be an expected behavior if the signature of the sorting function was expecting some kind of comparator.
compare: 'a -> 'a -> int
However in this case it can make the call drastically slower than say List.sortBy (as the latter's implementation is different), or even simply List.sortByDescending was implemented as say:
[<CompiledName("SortByDescending")>]
let inline sortByDescending projection list = List.sortBy (fun x -> -projection x) list
I wonder if such a PR might be smoothly accepted? I've never contributed before.
All reactions