mirror of
https://github.com/neovim/neovim.git
synced 2026-08-14 11:29:31 +00:00
Problem: sort() with "n", "N" or "f" converts an item to its number on
every comparison. For "n" that is a tv2string() plus strtod()
per comparison, so sorting a list of numbers turns each number
into a string and back O(n log n) times, dwarfing the sort.
Solution: Compute the numeric key of each item once, before the sort,
and compare the stored key (Samuel Schlesinger). Only the
builtin numeric compare modes are affected; uniq(), which
passes a bare list item to the compare function, and the
string and user-function paths are unchanged.
Sorting a list of 100000 numbers (min of 3, macOS arm64):
- sort(l, 'n'): 0.205s -> 0.017s
- sort(l, 'N'): 0.017s -> 0.010s
- sort(l, 'f'): 0.014s -> 0.010s
The result is identical, including that a string is still treated as 0
in "n" mode and that "N" keeps full 64-bit precision.
Add Test_sort_numeric_precomputed(): a large shuffled list sorted with
"n", mixed integers and floats, int64 values beyond the exact range of
a double for "N", and uniq() over the non-precomputed path.
closes: vim/vim#21003
c8c59db9df
Co-authored-by: Samuel Schlesinger <sgschlesinger@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>