Skip to content
Kavachकवच

Sorting

Also known as: sort order sorted ascending descending alphabetical radix quicksort merge sort stable compare key orderby sort_by case insensitive

● Beginner6 minBefore this: ListsSpec 14.2

list.sort() gives a sorted copy of a list of numbers, text, characters, Bools or tuples. sort_by(key) sorts anything else, by a key you choose.

fn main() {
    print([42, -7, 0, 1_000, 3].sort())
    const sizes: [UInt8] = [200, 3, 77]
    print(sizes.sort())
    print([10, 2, 33].sort().reverse())
}

The program ran and printed:

kavach run numbers.kav

[-7, 0, 3, 42, 1000][3, 77, 200][33, 10, 2]
numbers.kav: Kavach code, then what running it prints

Both give a new list and leave the original as it was. For the largest first, add .reverse().

How each type sorts

ItemsOrderMore
Int, Int8 … UInt64smallest first; negative numbers before 0See it →
Float, Float32smallest first; NaN after every number; 0.0 and -0.0 are equalSee it →
Decimal, BigIntby exact value, however many digitsSee it →
Stringby Unicode code point, character by character: uppercase before lowercase, accented letters after zSee it →
Charby Unicode code pointSee it →
Boolfalse before trueSee it →
Tuplesitem by item: by the first item, then the second when the first are equal, and so onSee it →
Records, unionsno order of their own: use sort_by with a keySee it →

A list holds one type, so there is no "mixed" list to sort: [1, "a"] doesn't compile. Data of mixed kinds is a list of records or of a union, sorted by a key you choose.

How whole numbers sort so fast

Comparing pairs of numbers takes about n × log n steps. For a long list of whole numbers, Kavach uses a radix sort instead: it places each number by one digit at a time, in a few passes over the list. Step through it:

17045759080224266
step 1 of 7

Eight numbers to sort. A radix sort never compares two numbers: it sorts by one digit at a time.

Which algorithm runs for which items, and why, is under "Go deeper" below.

One page for each form

Go deeper the why, for readers who want it

Which algorithm

SortingIn a program built by KavachWhy
Whole numbers and Char, under 512 itemsa comparison sort (Rust's unstable sort, a quicksort variant)for a short list, counting digits costs more than comparing; equal whole numbers can't be told apart, so keeping their order doesn't matter
Whole numbers and Char, 512 items or morea radix sort, 8 bits of each number at a timea few passes over the list instead of n × log n comparisons; bits that are the same in every number are skipped
… 65,536 items or morefirst split by the top 8 bits into 256 bucketseach bucket is small enough to sort inside the processor's cache, where memory is fastest
… 1,048,576 items or morethe buckets are sorted on all cores at oncethe buckets don't depend on each other, so the result is the same in any order
Floats, text, Decimal, BigInt, tuplesa stable merge sort (Rust's standard sort)these need comparing (NaN, text by code point), and equal items, like 0.0 and -0.0, keep their order
sort_bythe keys are worked out once each, then sorted with the stable merge sortyour key function runs once per item, not once per comparison, and equal keys keep their order

kavach run uses the stable merge sort for everything; the results are the same. A million numbers, sorted and checked:

fn main() {
    let xs: [Int] = []
    for i in 0..1_000_000 {
        xs.push((i * 7_919) % 1_000_003 - 500_000)
    }
    const sorted = xs.sort()
    let in_order = true
    for i in 1..sorted.len() {
        if sorted[i - 1] > sorted[i] {
            in_order = false
        }
    }
    print("{sorted.len()} numbers, in order: {in_order}")
    print("smallest {sorted[0]}, largest {sorted[sorted.len() - 1]}")
}

The program ran and printed:

kavach run large.kav

1000000 numbers, in order: truesmallest -500000, largest 500002
large.kav: Kavach code, then what running it prints

How much faster the radix sort is, against C++'s std::sort, is on Fast Sorting. Sorting runs on the CPU today, not on the GPU.

Check yourself

QUIZ 1 / 1pick one
What does ["banana", "Apple", "apple"].sort() give?