Sorting Algorithm Race

Race up to six sorts on one shuffled array, scored in operations, not seconds. Watch bubble sort crawl.

Clock 0 ops

Counts are real: every comparison and every write into the array is replayed. Runs entirely in your browser. Four sorts start on the track; Selection and Heap are one tap away in the chip row. Keys work once the track or a button is focused: Space starts, pauses or resumes, → steps one operation.

About the race

How the race stays fair. Every lane sorts the identical shuffled array — same heat number, same size, same shape — and on every tick each unfinished lane replays exactly the same number of real operations. The finishing order is therefore just the order of total operations. The clock above the lanes counts operations, never seconds, because timing JavaScript would measure your browser rather than the algorithm.

What counts as an operation. One comparison between two elements, or one write into the array. A swap is two writes. Merge sort copies values into a separate buffer before merging; those copies are not counted, but every value written back into the array is, even when it lands where it already was. Insertion sort holds its key aside, so comparing against the key is a comparison, and putting it back costs a write only if it actually moved. Shuffling is never counted.

Why a "slow" sort can win. Big-O describes how the work grows with size, not what happens on every array. This bubble sort stops after a pass with no swaps, so already-sorted input costs it n − 1 comparisons and no writes (63 operations at 64 bars, tying insertion sort for first; try Sorted). Insertion sort does almost nothing when every bar is already near its final spot. Here "nearly sorted" means the bars start in order and then max(1, n/10) pairs of neighbours are swapped, so at most n/10 pairs are out of order and no bar is more than n/10 places from home. On that data insertion sort finished ahead of all five others in every heat we tried (seeds 1 to 200, 16 to 256 bars), at just over n comparisons. On random bars the n² algorithms never came out ahead. Try Nearly sorted, then Reversed.

Why this quicksort slows down. It uses the last element as the pivot (the Lomuto scheme). On sorted or reversed data every partition peels off a single element, so it makes exactly n(n − 1)/2 comparisons: 2,016 for 64 bars, as many as selection sort. Few unique hurts it too, though less sharply: with only five distinct values, long runs of equal bars split lopsidedly, and at 128 bars Quick makes 2.5 to 3.4 times Merge's comparisons (seeds 1 to 200). Real libraries choose pivots more carefully, or switch algorithm when partitions go lopsided.

Big-O at a glance, and what the race does not measure.

AlgorithmWork
BubbleO(n²); best case O(n) with the early exit
InsertionO(n²); best case O(n)
SelectionO(n²) always — exactly n(n − 1)/2 comparisons
MergeO(n log n) always
QuickO(n log n) on average, O(n²) worst case
HeapO(n log n)

The race does not measure wall-clock time, cache effects or memory use. Production sorts are hybrids: V8's Array.prototype.sort uses TimSort, and C++ std::sort implementations typically use introsort.

Quick guide

Use cases, answers, and nearby tools

Compact below-tool notes that help first-run users and repeated visitors move faster without changing the main interface.

Chinese search: 排序演算法 賽跑、排序演算法 比較、哪個排序演算法最快、泡沫排序 快速排序 比較、氣泡排序 合併排序 堆積排序

How to use

Run a clean first pass

  1. Four sorts race by default; tap Selection or Heap to add them, or any chip to drop one (two stay). Choose a data shape (Random, Nearly sorted, Sorted, Reversed or Few unique) and how many bars. Every change, and Shuffle, starts a fresh heat at once; Reset takes it back to the blocks, waiting for Start race.
  2. Every lane sorts the same bars. Pause, Step one comparison or write at a time, or hit Finish to jump to the end; the tote board locks each result in as a lane crosses the line, and a winner line says who won and by how much.
  3. Press Race again for a new shuffle, or copy the link: it reproduces the exact same heat for anyone who opens it.

Examples

Real jobs this page helps with

  • Bubble vs quicksort on 64 random barsLeave the defaults and watch heat #2026. Quick finishes first on 625 operations and Merge on 687, while Bubble (4,099) and Insertion (2,255) are still part-way sorted; the strip along the bottom of each lane shows how far they have got.
  • Insertion sort's day: nearly sorted dataChoose Nearly sorted at 128 bars and race all six. Nearly sorted here means a few neighbouring bars swapped (at most 12 of the 127 neighbouring pairs out of order), so insertion sort needs just over 128 comparisons where Selection always makes exactly 8,128. Insertion finished first in every heat we tried (seeds 1 to 200, 145 to 163 operations at 128 bars).
  • Already sorted: bubble and insertion dead-heat on 63Choose Sorted at 64 bars and race all six. Bubble sort's early exit and insertion sort both finish in 63 operations (63 comparisons, no writes) and share first place; Merge needs 576 operations, and Quick and Selection each make 2,016 comparisons.
  • Reversed array: merge wins, bubble needs 6,048Choose Reversed at 64 bars with Bubble, Insertion, Selection, Merge and Quick. Merge finishes in 576 operations; bubble sort needs 6,048, which is 10.5 times the winner, and this quicksort's last-element pivot makes 2,016 comparisons.
  • Few unique values trip this quicksortChoose Few unique at 128 bars and race Merge against Quick. With only five distinct values the data is full of equal runs, the last-element pivot splits badly, and Quick makes 2.5 to 3.4 times Merge's comparisons (seeds 1 to 200); on heat #2026 that is 1,899 against 681.
  • Teacher mode: six lanes, slow, one operation at a timeSelect all six algorithms at 32 bars on Slow (60 operations a second). With these settings, heat #2026 (the number a bare link opens on), the first stamp lands after about four seconds, when Quick finishes its 227 operations; pause there, then press Step to show what one comparison and one write look like in Merge versus the lanes still running, with the colour key and each lane's last operation on screen, before you hit Finish.

FAQ

What people usually want to know

Which sorting algorithm is fastest?

On random data the O(n log n) algorithms — merge sort, quicksort and heap sort — do less work than bubble, insertion and selection sort, which are O(n²), and the gap widens with size: across seeds 1 to 200 the best of the three O(n²) sorts needed at least 1.4 times the operations of the slowest O(n log n) one at 64 bars, 2.2 times at 128 and 4.2 times at 256. In this race on 64 random bars merge sort and quicksort finish while bubble sort has thousands of operations left. But there is no single winner for every input: on nearly sorted data insertion sort beats all of them.

Why does bubble sort sometimes win?

This bubble sort stops as soon as a pass makes no swaps, so on already sorted data it needs only n − 1 comparisons and no writes — 63 operations for 64 bars, tying insertion sort for first (choose Sorted to see the dead heat). Big-O describes how work grows with size, not what happens on every specific array.

Why is quicksort slow on sorted or reversed data here?

This quicksort uses the last element as the pivot (the Lomuto scheme). On sorted or reversed input every partition peels off a single element, so it makes exactly n(n−1)/2 comparisons — 2,016 for 64 bars, as many as selection sort. Library implementations choose pivots more carefully or switch strategy to avoid this.

Is the race fair?

Yes. Every lane starts from the identical shuffled array, and on every tick each unfinished lane replays exactly the same number of real operations. The finishing order is therefore the order of total operations, and the counters show the comparisons and writes each algorithm actually performed.

What counts as an operation?

One comparison between two elements, or one write into the array. A swap counts as two writes. Merge sort copies values into a separate buffer before merging; those copies are not counted, but every value written back into the array is.