Skip to content

Improved slice.sort | changed _smoothsort to _generic_quicksort - #7423

Open
TheRadischen wants to merge 15 commits into
odin-lang:masterfrom
TheRadischen:unstable_sort
Open

Improved slice.sort | changed _smoothsort to _generic_quicksort#7423
TheRadischen wants to merge 15 commits into
odin-lang:masterfrom
TheRadischen:unstable_sort

Conversation

@TheRadischen

@TheRadischen TheRadischen commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Old implementation: Smoothsort

negativ:
hard to read/understand
slow on random data
2x more comparisons compared to most standart sorts

positiv:
fast on almost sorted data

New Implementation: Quicksort (lumoto partitioning)

negativ:
low adaptability

positiv:
easier to read (nice for core)
1.5 - 3x faster on average
unrolled recursion for bigger partition so we dont blow up the stack

Conclusion

Just like old implementaion, the new sort only gets created once and so doesnt bloat code size, bc of parapoly
drop in replacement, no change required for anything else
improvement upon #6739
similar LOC

Tests

also added a bunch of tests for most sort procs

Benchmark

code: https://github.com/TheRadischen/tests/blob/main/slice_sort/test.odin
uses slice.sort, so youd need to change branches to see the changes

New Implementation

test_highly_ordered(100_000 int)
size 100000    lumoto:  5.5305ms

test_many_similar(100_000 int)
size 100000    lumoto:  1.6337ms

test_random(100_000 int)
size 100000    lumoto:  10.2806ms

test_slice_with_data_indecies_100_000
size 100000    lumoto:  12.6696ms

slice.big(100_00 1600 byte )
size 100000    lumoto:  8.0777ms

sort_with_indecies(int)
iter 10000 size 10  in cycles / item  slice.sort:  66
iter 10000 size 100  in cycles / item  slice.sort:  123
iter 1000 size 1000  in cycles / item  slice.sort:  171
iter 100 size 10000  in cycles / item  slice.sort:  240
iter 10 size 100000  in cycles / item  slice.sort:  362

sort_by_with_indecies([10]int)
iter 10000 size 10  in cycles / item  slice.sort:  86
iter 10000 size 100  in cycles / item  slice.sort:  199
iter 1000 size 1000  in cycles / item  slice.sort:  328
iter 100 size 10000  in cycles / item  slice.sort:  456
iter 10 size 100000  in cycles / item  slice.sort:  830

Old implementation:

test_highly_ordered(100_000 int)
size 100000    _smoothsort:  4.2111ms // only winning case

test_many_similar(100_000 int)
size 100000    _smoothsort:  17.2895ms

test_random(100_000 int)
size 100000    _smoothsort:  21.4528ms

test_slice_with_data_indecies_100_000
size 100000    _smoothsort:  46.9443ms

slice.big(100_00 1600 byte )
size 100000    _smoothsort:  15.2466ms

sort_with_indecies(int)
iter 10000 size 10  in cycles / item  slice.sort:  90
iter 10000 size 100  in cycles / item  slice.sort:  191
iter 1000 size 1000  in cycles / item  slice.sort:  301
iter 100 size 10000  in cycles / item  slice.sort:  427
iter 10 size 100000  in cycles / item  slice.sort:  658

sort_by_with_indecies([10]int)
iter 10000 size 10  in cycles / item  slice.sort:  126
iter 10000 size 100  in cycles / item  slice.sort:  282
iter 1000 size 1000  in cycles / item  slice.sort:  490
iter 100 size 10000  in cycles / item  slice.sort:  715
iter 10 size 100000  in cycles / item  slice.sort:  1519

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant