Skip to content

Use type-specialized comparators in list.sort() like CPython's listsort.c #8450

Description

@kangdora

Summary

Follow-up to #8421. The sorting algorithm now matches CPython's powersort, but every comparison still goes through full rich_compare_bool dispatch. Most of CPython's remaining speed advantage on list.sort() comes from its pre-scan type specialization, not from the algorithm itself.

Details

CPython's listsort.c scans the list once before sorting and, when every element is the same exact type, swaps the generic safe_object_compare for a direct comparison function that skips method dispatch entirely:

  • unsafe_long_compare for int
  • unsafe_latin_compare for latin-1 str
  • unsafe_float_compare for float
  • unsafe_tuple_compare for tuples of the above

Plan for RustPython:

  • Implement the pre-scan and specialized comparators in do_sort (crates/vm/src/builtins/list.rs), where the comparison closure is built — crates/vm/src/sorting.rs stays generic over is_lt.
  • When key= is used, apply the scan to the key vector instead of the elements.
  • Correctness guard: any subclass (which may override __lt__) must fall back to the generic path, matching CPython's exact-type check.

The O(n) scan is negligible next to the O(n log n) comparisons it speeds up. I'd validate with benchmarks across sizes (1k / 100k / 1M) and element types (int / float / str / arbitrary objects).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions