Compare sorting algorithms' performance: Difference between revisions

Added Sidef
(Added Kotlin)
(Added Sidef)
 
(29 intermediate revisions by 11 users not shown)
Line 1:
{{task|Sorting Algorithms}}
[[Category:Sorting]]
{{Sorting Algorithm}}
 
Measure a relative performance of sorting algorithms implementations.
 
Line 5 ⟶ 8:
 
Consider three type of input sequences:
:*   ones: sequence of all ''1'''s.   Example: {1, 1, 1, 1, 1}
:*   range: ascending sequence, i.e. already sorted.   Example: {1, 2, 3, 10, 15}
:*   shuffled range: sequence with elements randomly distributed.   Example: {5, 3, 9, 6, 8}
 
 
Consider at least two different sorting functions (different algorithms or/and different implementation of the same algorithm).
 
For example, consider [[Bubble Sort]], [[Insertion sort]], [[Quicksort]] or/and implementations of Quicksort with different pivot selection mechanisms. Where possible, use existing implementations.
For example, consider [[Bubble Sort]], [[Insertion sort]], [[Quicksort]] or/and implementations of Quicksort with different pivot selection mechanisms.   Where possible, use existing implementations.
 
Preliminary subtask:
:*   [[Bubble Sort]], [[Insertion sort]], [[Quicksort]], [[Radix sort]], [[Shell sort]]
:*   [[Query Performance]]
:*   [[Write float arrays to a text file]]
:*   [[Plot x, y arrays]]
:*   [[Polynomial Fitting]]
 
 
General steps:
:#   Define sorting routines to be considered.
:#   Define appropriate sequence generators and write timings.
:#   Plot timings.
:#   What conclusions about relative performance of the sorting routines could be made based on the plots?
<br><br>
 
=={{header|AutoHotkey}}==
{{in progress|lang=AutoHotkey|day=16|month=1|year=2010}}
<langsyntaxhighlight lang="ahk">; BUGGY - FIX
 
#Persistent
Line 330 ⟶ 337:
Sort, var, N D`,
Return var
}</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#Macro sort_1(sortname)
Rset buffer, #sortname
Print buffer;
copy_array(rev(), sort())
t1 = Timer
sortname(sort())
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec";
copy_array(ran(), sort())
t1 = Timer
sortname(sort())
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec";
t1 = Timer
sortname(sort())
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec";
copy_array(eq(), sort())
t1 = Timer
sortname(sort())
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec"
#EndMacro
 
#Macro sort_2(sortname)
Rset buffer, #sortname
Print buffer;
copy_array(rev(), sort())
t1 = Timer
sortname(sort(), Lbound(sort), Ubound(sort))
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec";
copy_array(ran(), sort())
t1 = Timer
sortname(sort(), Lbound(sort), Ubound(sort))
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec";
t1 = Timer
sortname(sort(), Lbound(sort), Ubound(sort))
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec";
copy_array(eq(),sort())
t1 = Timer
sortname(sort(), Lbound(sort), Ubound(sort))
t2 = Timer - t1
Print Using " ###.###&"; t2; " sec"
#EndMacro
 
 
Sub bubbleSort(array() As Double)
Dim As Integer i, lb = Lbound(array), ub = Ubound(array)
For p1 As Uinteger = 0 To ub - 1
For p2 As Uinteger = p1 + 1 To ub
'change >= to > , don't swap if they are equal
If (array(p1)) > (array(p2)) Then Swap array(p1), array(p2)
Next p2
Next p1
For i = lb To ub - 1
If array(i) > array(i + 1) Then Beep
Next
End Sub
 
Sub exchangeSort(array() As Double)
Dim As Uinteger i, j, min, ub = Ubound(array)
For i = 0 To ub
min = i
For j = i+1 To ub
If (array(j) < array(min)) Then min = j
Next j
If min > i Then Swap array(i), array(min)
Next i
End Sub
 
Sub insertionSort(array() As Double)
Dim As Uinteger ub = Ubound(array)
Dim As Uinteger i, j, temp, temp2
For i = 1 To ub
temp = array(i)
temp2 = temp
j = i
While j >= 1 Andalso array(j-1) > temp2
array(j) = array(j - 1)
j -= 1
Wend
array(j) = temp
Next i
End Sub
 
Sub siftdown(hs() As Double, inicio As Ulong, final As Ulong)
Dim As Ulong root = inicio
Dim As Long lb = Lbound(hs)
While root * 2 + 1 <= final
Dim As Ulong child = root * 2 + 1
If (child + 1 <= final) Andalso (hs(lb + child) < hs(lb + child + 1)) Then child += 1
If hs(lb + root) < hs(lb + child) Then
Swap hs(lb + root), hs(lb + child)
root = child
Else
Return
End If
Wend
End Sub
Sub heapSort(array() As Double)
Dim As Long lb = Lbound(array)
Dim As Ulong count = Ubound(array) - lb + 1
Dim As Long inicio = (count - 2) \ 2
Dim As Ulong final = count - 1
While inicio >= 0
siftdown(array(), inicio, final)
inicio -= 1
Wend
While final > 0
Swap array(lb + final), array(lb)
final -= 1
siftdown(array(), 0, final)
Wend
End Sub
 
Sub shellSort(array() As Double)
Dim As Uinteger lb = Lbound(array), ub = Ubound(array)
Dim As Uinteger i, inc = ub - lb
Dim As Boolean done
Do
inc = Int(inc / 2.2)
If inc < 1 Then inc = 1
Do
done = false
For i = lb To ub - inc
' reemplace "<" con ">" para ordenación descendente
If array(i) > array(i + inc) Then
Swap array(i), array(i + inc)
done = true
End If
Next i
Loop Until done = false
Loop Until inc = 1
End Sub
 
Sub quickSort(array() As Double, l As Integer, r As Integer)
Dim As Uinteger size = r - l +1
If size < 2 Then Exit Sub
Dim As Integer i = l, j = r
Dim As Double pivot = array(l + size \ 2)
Do
While array(i) < pivot
i += 1
Wend
While pivot < array(j)
j -= 1
Wend
If i <= j Then
Swap array(i), array(j)
i += 1
j -= 1
End If
Loop Until i > j
If l < j Then quickSort(array(), l, j)
If i < r Then quickSort(array(), i, r)
End Sub
 
Sub rapidSort (array()As Double, inicio As Integer, final As Integer)
Dim As Integer n, wert, nptr, arr, rep
Dim As Integer LoVal = array(inicio), HiVal = array(final)
For n = inicio To final
If LoVal> array(n) Then LoVal = array(n)
If HiVal< array(n) Then HiVal = array(n)
Next
Redim SortArray(LoVal To HiVal) As Double
For n = inicio To final
wert = array(n)
SortArray(wert) += 1
Next
nptr = inicio-1
For arr = LoVal To HiVal
rep = SortArray(arr)
For n = 1 To rep
nptr += 1
array(nptr) = arr
Next
Next
Erase SortArray
End Sub
 
Sub copy_array(s() As Double, d() As Double)
For x As Integer = Lbound(s) To Ubound(s)
d(x) = s(x)
Next
End Sub
 
 
Dim As Integer x, max = 1e5
Dim As Double t1, t2, ran(0 To max), sort(0 To max), rev(0 To max), eq(0 To max)
Dim As String buffer = Space(14)
 
Cls
' fill ran() with random numbers and eq() with same number
For x = 0 To max
ran(x) = Rnd
rev(x) = ran(x) ' make reverse array equal to random array
eq(x) = 1/3
Next x
 
For x = Lbound(rev) To (Ubound(rev) \ 2)
Swap rev(x), rev(Ubound(rev) - x)
Next x
 
Print !"Test times in sec\nArray size ="; max
Print !"\n *Reversed* *Random* *Sorted* *All ones*"
 
sort_1(bubbleSort)
sort_1(exchangeSort)
sort_1(insertionSort)
sort_1(heapSort)
sort_1(shellSort)
sort_2(quickSort)
sort_2(rapidSort)
Sleep</syntaxhighlight>
{{out}}
<pre>Test times in sec
Array size = 100000
 
*Reversed* *Random* *Sorted* *All ones*
bubbleSort 31.645 sec 31.560 sec 12.765 sec 12.754 sec
exchangeSort 12.706 sec 12.708 sec 12.713 sec 12.700 sec
insertionSort 4.724 sec 4.739 sec 0.004 sec 0.004 sec
heapSort 0.028 sec 0.029 sec 0.021 sec 0.002 sec
shellSort 0.049 sec 0.049 sec 0.003 sec 0.003 sec
quickSort 0.013 sec 0.013 sec 0.004 sec 0.005 sec
rapidSort 0.004 sec 0.004 sec 0.004 sec 0.007 sec</pre>
 
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> HIMEM = PAGE + 2000000
INSTALL @lib$+"SORTLIB"
INSTALL @lib$+"TIMERLIB"
Line 496 ⟶ 747:
ENDWHILE
a%() += l%
ENDPROC</langsyntaxhighlight>
'''Output:'''
<pre>
Line 540 ⟶ 791:
===Sequence generators===
<tt>csequence.h</tt>
<langsyntaxhighlight lang="c">#ifndef _CSEQUENCE_H
#define _CSEQUENCE_H
#include <stdlib.h>
Line 548 ⟶ 799:
void fillwithrrange(double *v, int n);
void shuffledrange(double *v, int n);
#endif</langsyntaxhighlight>
<tt>csequence.c</tt>
<langsyntaxhighlight lang="c">#include "csequence.h"
 
static double fill_constant;
Line 580 ⟶ 831:
v[r] = t;
}
}</langsyntaxhighlight>
===Write timings===
We shall use the code from [[Query Performance]]. Since the ''action'' is a generic function with a single argument, we need ''wrappers'' which encapsule each sorting algorithms we want to test.
 
<tt>writetimings.h</tt>
<langsyntaxhighlight lang="c">#ifndef _WRITETIMINGS_H
#define _WRITETIMINGS_H
#include "sorts.h"
Line 623 ⟶ 874:
};
typedef struct seqdef seqdef_t;
#endif</langsyntaxhighlight>
<tt>writetimings.c</tt>
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 728 ⟶ 979:
free(tobesorted);
return 0;
}</langsyntaxhighlight>
This code produce several files with the following naming convention:
* data_''algorithm''_''sequence''.dat
Where ''algorithm'' is one of the following: insertion, merge, shell, quick, qsort (the quicksort in the libc library) (bubble sort became too slow for longest sequences). ''Sequence'' is ''c1'' (constant value 1), ''rr'' (reverse range), ''sr'' (shufled range). These data can be easily plotted by Gnuplot, which can also do fitting. Instead we do our fitting using [[Polynomial Fitting]].
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Line 761 ⟶ 1,012:
 
return 0;
}</langsyntaxhighlight>
Here we search for a fit with C<sub>0</sub>+C<sub>1</sub>x "in the log scale", since we supposed the data, once plotted on a logscale graph, can be fitted by a line. We can use e.g. a shell one-liner to produce the parameters for the line for each data file previously output. In particular I've used the following
<pre>for el in *.dat ; do fitdata <$el >${el%.dat}.fd ; done</pre>
Line 787 ⟶ 1,038:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.container, std.datetime,
std.random, std.typetuple;
 
Line 934 ⟶ 1,185:
nRuns.benchmark!(randomBubble, randomInsertion,
randomHeap, randomBuiltIn).show;
}</langsyntaxhighlight>
{{out}}
<pre>Timings in microseconds:
Line 959 ⟶ 1,210:
The sort routines are borrowed from [http://rosettacode.org/wiki/Sorting_algorithms/Bubble_sort bubble sort], [http://rosettacode.org/wiki/Sorting_algorithms/Insertion_sort insertion sort] and [http://rosettacode.org/wiki/Sorting_algorithms/Quicksort quick sort]. Plots by [https://github.com/psyeugenic/eplot eplot].
Bubble sort does [http://github.com/ebengt/rosettacode/tree/master/graphs/ones.png ones] and [http://github.com/ebengt/rosettacode/tree/master/graphs/ranges.png ranges] best. Insertion sort does [http://github.com/ebengt/rosettacode/tree/master/graphs/reversed_ranges.png reversed ranges] best. Quick sort handles [http://github.com/ebengt/rosettacode/tree/master/graphs/shuffleds.png shuffled numbers] best.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( compare_sorting_algorithms ).
 
Line 987 ⟶ 1,238:
{Time, _Result} = timer:tc( fun() -> Fun( List_fun(N) ) end ),
{math:log10(N), math:log10(Time)}.
</syntaxhighlight>
</lang>
 
=={{header|Go}}==
{{libheader|gonum/plot}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,212 ⟶ 1,463:
ps.Shape = plotutil.DefaultGlyphShapes[dx]
p.Add(pl, ps)
}</langsyntaxhighlight>
{{out}}
[[file:GoComp.png|right|Comparison]]
Line 1,221 ⟶ 1,472:
On random data (triangles) insertion and bubble sort show worse performance than quicksort.
<br clear=all>
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.Time.Clock
import Data.List
 
type Time = Integer
type Sorter a = [a] -> [a]
 
-- Simple timing function (in microseconds)
timed :: IO a -> IO (a, Time)
timed prog = do
t0 <- getCurrentTime
x <- prog
t1 <- x `seq` getCurrentTime
return (x, ceiling $ 1000000 * diffUTCTime t1 t0)
-- testing sorting algorithm on a given set
test :: [a] -> Sorter a -> IO [(Int, Time)]
test set srt = mapM (timed . run) ns
where
ns = take 15 $ iterate (\x -> (x * 5) `div` 3) 10
run n = pure $ length $ srt (take n set)
 
-- sample sets
constant = repeat 1
 
presorted = [1..]
 
random = (`mod` 100) <$> iterate step 42
where
step x = (x * a + c) `mod` m
(a, c, m) = (1103515245, 12345, 2^31-1)</syntaxhighlight>
 
As a result of testing we get the list of tuples: length of a list and time in microseconds:
<pre>λ> test ones sort
[(10,9),(16,7),(26,5),(43,5),(71,6),(118,8),(196,12),(326,18),(543,28),(905,41),(1508,68),(2513,108),(4188,191),(6980,303),(11633,484)]
λ> test rand sort
[(10,8),(16,7),(26,7),(43,9),(71,15),(118,24),(196,43),(326,82),(543,136),(905,270),(1508,482),(2513,1004),(4188,1926),(6980,4612),(11633,7286)]</pre>
 
Different sorting methods:
 
<syntaxhighlight lang="haskell">-- Naive quick sort
qsort :: Ord a => Sorter a
qsort [] = []
qsort (h:t) = qsort (filter (< h) t) ++ [h] ++ qsort (filter (>= h) t)
-- Bubble sort
bsort :: Ord a => Sorter a
bsort s = case _bsort s of
t | t == s -> t
| otherwise -> bsort t
where _bsort (x:x2:xs) | x > x2 = x2:_bsort (x:xs)
| otherwise = x :_bsort (x2:xs)
_bsort s = s
-- Insertion sort
isort :: Ord a => Sorter a
isort = foldr insert []</syntaxhighlight>
 
Finally, charting routines and the task implementation:
<syntaxhighlight lang="haskell">-- chart appears to be logarithmic scale on both axes
barChart :: Char -> [(Int, Time)] -> [String]
barChart ch lst = bar . scale <$> lst
where
scale (x,y) = (x, round $ (3*) $ log $ fromIntegral y)
bar (x,y) = show x ++ "\t" ++ replicate y ' ' ++ [ch]
over :: String -> String -> String
over s1 s2 = take n $ zipWith f (pad s1) (pad s2)
where
f ' ' c = c
f c ' ' = c
f y _ = y
pad = (++ repeat ' ')
n = length s1 `max` length s2
 
comparison :: Ord a => [Sorter a] -> [Char] -> [a] -> IO ()
comparison sortings chars set = do
results <- mapM (test set) sortings
let charts = zipWith barChart chars results
putStrLn $ replicate 50 '-'
mapM_ putStrLn $ foldl1 (zipWith over) charts
putStrLn $ replicate 50 '-'
let times = map (fromInteger . snd) <$> results
let ratios = mean . zipWith (flip (/)) (head times) <$> times
putStrLn "Comparing average time ratios:"
mapM_ putStrLn $ zipWith (\r s -> [s] ++ ": " ++ show r) ratios chars
where
mean lst = sum lst / genericLength lst
 
main = do
putStrLn "comparing on list of ones"
run ones
putStrLn "\ncomparing on presorted list"
run seqn
putStrLn "\ncomparing on shuffled list"
run rand
where
run = comparison [sort, isort, qsort, bsort] "siqb"</syntaxhighlight>
 
<pre>λ> main
comparing on list of ones
--------------------------------------------------
10 is b q
16 is b q
26 s b q
43 si b q
71 si b q
118 si b q
196 si b q
326 si b q
543 s i b q
905 s i b q
1508 s i b q
2513 s i b q
4188 s i b q
6980 s i b q
11633 s i b q
--------------------------------------------------
Comparing average time ratios:
s: 1.0
i: 1.9768226698141058
q: 4948.447011286744
b: 8.648711819912956
 
comparing on presorted list
--------------------------------------------------
10 isb q
16 s b q
26 s b q
43 i s b q
71 is b q
118 s b q
196 s b q
326 si b q
543 si b q
905 si b q
1508 si b q
2513 si b q
4188 s i b q
6980 s i b q
11633 s i b q
--------------------------------------------------
Comparing average time ratios:
s: 1.0
i: 1.2828547504398033
q: 2586.058542372048
b: 4.478306385307422
 
comparing on shuffled list
--------------------------------------------------
10 i qs
16 is q b
26 s q b
43 is q b
71 s q b
118 si q b
196 si q b
326 s i b
543 s qi b
905 s i b
1508 s q i b
2513 s q i b
4188 s q i b
6980 s q i b
11633 s q i b
--------------------------------------------------
Comparing average time ratios:
s: 1.0
i: 33.0167854766955
q: 4.778965210071694
b: 920.9348663725772</pre>
 
We see that well known Haskell meme -- naive quicksort, is total mess on degenerate cases, and it does much better in general, still being significantly more slow then standard implementation. This tests were done in GHCi. Lazy Haskell program may be drastically rewritten and optimized during compilation. Let's see how it goes after compilation:
 
<pre>$ ghc -O2 CompareSort.hs
[1 of 1] Compiling Main ( CompareSort.hs, CompareSort.o )
Linking CompareSort ...
$ ./CompareSort
comparing on list of ones
--------------------------------------------------
10 i q s
16 s q
26 i s q
43 bs i q
71 ibs q
118 ibs q
196 ib s q
326 i bs q
543 bis q
905 i bs q
1508 ib s q
2513 ibs q
4188 ib s q
6980 si q
11633 si q
--------------------------------------------------
Comparing average time ratios:
s: 1.0
i: 0.9148588587463226
q: 751.3527462449417
b: 0.774109602468018
 
comparing on presorted list
--------------------------------------------------
10 i s
16 s q
26 s q
43 i s q
71 s q
118 sb q
196 is q
326 isb q
543 sb q
905 sb i q
1508 is q
2513 sb q
4188 is q
6980 ibs q
11633 s q
--------------------------------------------------
Comparing average time ratios:
s: 1.0
i: 1.114052564981571
q: 577.8734457264803
b: 1.1171025867573912
 
comparing on shuffled list
--------------------------------------------------
10 iqs
16 is
26 isb
43 sq b
71 si b
118 si b
196 s i b
326 sq i b
543 s i b
905 sq i b
1508 s q i b
2513 s q i b
4188 s q i b
6980 s q i b
11633 s q i b
--------------------------------------------------
Comparing average time ratios:
s: 1.0
i: 29.346876854773274
q: 1.3750763918038253
b: 71.47503300525689</pre>
 
Even though quicksort still sucks on degenerate lists, it does really much better when compiled. Bubble sort had also improved it's rate, in contrast to insertion sort which didn't gain anything from compilation.
 
=={{header|J}}==
<syntaxhighlight lang="j">
<lang j>
NB. extracts from other rosetta code projects
ts=: 6!:2, 7!:2@]
Line 1,306 ⟶ 1,809:
(_*pts) + n +./ .*1 0 2|:coef&(p."1) plot x
)
</syntaxhighlight>
</lang>
 
<pre>
Line 1,457 ⟶ 1,960:
 
The data fit curves of the character cell graph were combined with GCD +. function. This explains "1"s or other strange values where these curves intersect. Finally the scatter plots were multiplied by infinity and added to the best fit curves. The points didn't show up well using the same values as the curves.
 
=={{header|JavaScript}}==
<syntaxhighlight lang="javascript">
function swap(a, i, j){
var t = a[i]
a[i] = a[j]
a[j] = t
}
 
// Heap Sort
 
function heap_sort(a){
var n = a.length
function heapify(i){
var t = a[i]
while (true){
var l = 2 * i + 1, r = l + 1
var m = r < n ? (a[l] > a[r] ? l : r) : (l < n ? l : i)
if (m != i && a[m] > t){
a[i] = a[m]
i = m
}
else{
break
}
}
a[i] = t;
}
for (let i = Math.floor(n / 2) - 1; i >= 0; i--){
heapify(i)
}
for (let i = n - 1; i >= 1; i--){
swap(a, 0, i)
n--
heapify(0)
}
}
 
// Merge Sort
 
function merge_sort(a){
var b = new Array(a.length)
function rec(l, r){
if (l < r){
var m = Math.floor((l + r) / 2)
rec(l, m)
rec(m + 1, r)
var i = l, j = m + 1, k = 0;
 
while (i <= m && j <= r) b[k++] = (a[i] > a[j] ? a[j++] : a[i++])
while (j <= r) b[k++] = a[j++]
while (i <= m) b[k++] = a[i++]
 
for (k = l; k <= r; k++){
a[k] = b[k - l]
}
}
}
rec(0, a.length-1)
}
 
// Quick Sort
 
function quick_sort(a){
function rec(l, r){
if (l < r){
var p = a[l + Math.floor((r - l + 1)*Math.random())]
var i = l, j = l, k = r
while (j <= k){
if (a[j] < p){
swap(a, i++, j++)
}
else if (a[j] > p){
swap(a, j, k--)
}
else{
j++
}
}
 
rec(l, i - 1)
rec(k + 1, r)
}
}
rec(0, a.length - 1)
}
 
// Shell Sort
 
function shell_sort(a){
var n = a.length
var gaps = [100894, 44842, 19930, 8858, 3937, 1750, 701, 301, 132, 57, 23, 10, 4, 1]
for (let x of gaps){
for (let i = x; i < n; i++){
var t = a[i], j;
for (j = i; j >= x && a[j - x] > t; j -= x){
a[j] = a[j - x];
}
a[j] = t;
}
}
}
 
// Comb Sort (+ Insertion sort optimization)
 
function comb_sort(a){
var n = a.length
for (let x = n; x >= 10; x = Math.floor(x / 1.3)){
for (let i = 0; i + x < n; i++){
if (a[i] > a[i + x]){
swap(a, i, i + x)
}
}
}
 
for (let i = 1; i < n; i++){
var t = a[i], j;
for (j = i; j > 0 && a[j - 1] > t; j--){
a[j] = a[j - 1]
}
a[j] = t;
}
}
 
// Test
 
function test(f, g, e){
var res = ""
for (let n of e){
var a = new Array(n)
var s = 0
for (let k = 0; k < 10; k++){
for (let i = 0; i < n; i++){
a[i] = g(i)
}
var start = Date.now()
f(a)
s += Date.now() - start
}
res += Math.round(s / 10) + "\t"
}
return res
}
 
// Main
 
var e = [5000, 10000, 100000, 500000, 1000000, 2000000]
 
var sOut = "Test times in ms\n\nElements\t" + e.join("\t") + "\n\n"
 
sOut += "*All ones*\n"
sOut += "heap_sort\t" + test(heap_sort, (x => 1), e) + "\n"
sOut += "quick_sort\t" + test(quick_sort, (x => 1), e) + "\n"
sOut += "merge_sort\t" + test(merge_sort, (x => 1), e) + "\n"
sOut += "shell_sort\t" + test(shell_sort, (x => 1), e) + "\n"
sOut += "comb_sort\t" + test(comb_sort, (x => 1), e) + "\n\n"
 
sOut += "*Sorted*\n"
sOut += "heap_sort\t" + test(heap_sort, (x => x), e) + "\n"
sOut += "quick_sort\t" + test(quick_sort, (x => x), e) + "\n"
sOut += "merge_sort\t" + test(merge_sort, (x => x), e) + "\n"
sOut += "shell_sort\t" + test(shell_sort, (x => x), e) + "\n"
sOut += "comb_sort\t" + test(comb_sort, (x => x), e) + "\n\n"
 
sOut += "*Random*\n"
sOut += "heap_sort\t" + test(heap_sort, (x => Math.random()), e) + "\n"
sOut += "quick_sort\t" + test(quick_sort, (x => Math.random()), e) + "\n"
sOut += "merge_sort\t" + test(merge_sort, (x => Math.random()), e) + "\n"
sOut += "shell_sort\t" + test(shell_sort, (x => Math.random()), e) + "\n"
sOut += "comb_sort\t" + test(comb_sort, (x => Math.random()), e) + "\n"
 
console.log(sOut)
</syntaxhighlight>
{{out}}
<pre>
Test times in ms
 
Elements 5000 10000 100000 500000 1000000 2000000
 
*All ones*
heap_sort 0 0 0 3 5 11
quick_sort 0 0 0 1 2 4
merge_sort 1 1 9 50 103 216
shell_sort 1 0 4 19 39 78
comb_sort 1 0 6 35 75 160
 
*Sorted*
heap_sort 1 1 7 38 79 162
quick_sort 1 1 10 54 111 230
merge_sort 1 1 9 50 103 217
shell_sort 0 0 3 19 39 78
comb_sort 0 1 6 34 75 160
 
*Random*
heap_sort 1 1 12 71 161 383
quick_sort 1 1 15 85 177 373
merge_sort 1 1 18 103 215 451
shell_sort 1 1 15 89 188 397
comb_sort 1 1 12 74 159 343
</pre>
 
=={{header|Julia}}==
Julia comes with the InsertionSort, MergeSort, and QuickSort routines built into the Base.Sort module. Here is a comparison using those system algorithms and with integers.
<syntaxhighlight lang="julia">
function comparesorts(tosort)
a = shuffle(["i", "m", "q"])
iavg = mavg = qavg = 0.0
for c in a
if c == "i"
iavg = sum(i -> @elapsed(sort(tosort, alg=InsertionSort)), 1:100) / 100.0
elseif c == "m"
mavg = sum(i -> @elapsed(sort(tosort, alg=MergeSort)), 1:100) / 100.0
elseif c == "q"
qavg = sum(i -> @elapsed(sort(tosort, alg=QuickSort)), 1:100) / 100.0
end
end
iavg, mavg, qavg
end
 
allones = fill(1, 40000)
sequential = collect(1:40000)
randomized = collect(shuffle(1:40000))
 
comparesorts(allones)
comparesorts(allones)
iavg, mavg, qavg = comparesorts(allones)
println("Average sort times for 40000 ones:")
println("\tinsertion sort:\t$iavg\n\tmerge sort:\t$mavg\n\tquick sort\t$qavg")
 
comparesorts(sequential)
comparesorts(sequential)
iavg, mavg, qavg = comparesorts(sequential)
println("Average sort times for 40000 presorted:")
println("\tinsertion sort:\t$iavg\n\tmerge sort:\t$mavg\n\tquick sort\t$qavg")
 
comparesorts(randomized)
comparesorts(randomized)
iavg, mavg, qavg = comparesorts(randomized)
println("Average sort times for 40000 randomized:")
println("\tinsertion sort:\t$iavg\n\tmerge sort:\t$mavg\n\tquick sort\t$qavg")
</syntaxhighlight>
<pre>Average sort times for 40000 ones:
insertion sort: 0.00036058316000000005
merge sort: 0.00040099004999999996
quick sort 0.0003586394400000001
Average sort times for 40000 presorted:
insertion sort: 0.0003141142199999999
merge sort: 0.0007967360000000003
quick sort 0.0005601127399999998
Average sort times for 40000 randomized:
insertion sort: 0.2190664327599999
merge sort: 0.0028818907399999986
quick sort 0.0023325933899999997
</pre>
 
=={{header|Kotlin}}==
Line 1,468 ⟶ 2,241:
 
Although it would be easy enough to plot the results graphically using an external library such as JFreePlot, there doesn't seem much point when we can no longer upload images to RC. I've therefore presented the results in tabular form on the terminal which is good enough to detect significant trends.
<langsyntaxhighlight lang="scala">// Version 1.2.31
 
import java.util.Random
Line 1,609 ⟶ 2,382:
println("\n")
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,646 ⟶ 2,419:
On the other hand, bubble and insertion sorts are much quicker than the other methods for constant data and for data which is already sorted in an ascending direction, bubble sort being the faster of the two.
 
=={{header|PhixMathematica}}/{{header|Wolfram Language}}==
Comparing bubble and shell sort:
{{libheader|pGUI}}
<syntaxhighlight lang="mathematica">ClearAll[BubbleSort,ShellSort]
<lang Phix>--
BubbleSort[in_List]:=Module[{x=in,l=Length[in],swapped},swapped=True;
-- demo\rosetta\Compare_sorting_algorithms.exw
While[swapped,swapped=False;
--
Do[If[x[[i]]>x[[i+1]],x[[{i,i+1}]]//=Reverse;
constant XQS = 01 -- (set to 1 to exclude quick_sort and shell_sort from ones)
swapped=True;],{i,l-1}];];
x]
ShellSort[lst_]:=Module[{list=lst,incr,temp,i,j},incr=Round[Length[list]/2];
While[incr>0,For[i=incr+1,i<=Length[list],i++,temp=list[[i]];j=i;
While[(j>=(incr+1))&&(list[[j-incr]]>temp),list[[j]]=list[[j-incr]];j=j-incr;];
list[[j]]=temp;];
If[incr==2,incr=1,incr=Round[incr/2.2]]];list
]
 
times=Table[
include pGUI.e
arr=ConstantArray[1,n];
t1={{n,AbsoluteTiming[BubbleSort[arr];][[1]]},{n,AbsoluteTiming[ShellSort[arr];][[1]]}};
arr=Sort[RandomInteger[{10^6},n]];
t2={{n,AbsoluteTiming[BubbleSort[arr];][[1]]},{n,AbsoluteTiming[ShellSort[arr];][[1]]}};
arr=RandomInteger[{10^6},n];
t3={{n,AbsoluteTiming[BubbleSort[arr];][[1]]},{n,AbsoluteTiming[ShellSort[arr];][[1]]}};
{t1,t2,t3}
,
{n,2^Range[13]}
];
 
ListLogLogPlot[Transpose@times[[All,1]],PlotLegends->{"Bubble","Shell"},PlotLabel->"Ones"]
Ihandle dlg, tabs, plot
ListLogLogPlot[Transpose@times[[All,2]],PlotLegends->{"Bubble","Shell"},PlotLabel->"Ascending integers"]
Ihandles plots
ListLogLogPlot[Transpose@times[[All,3]],PlotLegends->{"Bubble","Shell"},PlotLabel->"Shuffled"]</syntaxhighlight>
{{out}}
Outputs three graphs on a log-log scales showing the size of the array and the time taken, for each of the three different arrays.
 
=={{header|Nim}}==
function quick_sort2(sequence x)
{{trans|Kotlin}}
integer n = length(x), c, mid, midn
object xi, midval
sequence left = {}, right = {}
 
This is a direct translation of the Kotlin program. We have added the sorting algorithm provided by Nim standard library which is a merge sort. For this reason, we have been constrained to annotate the sorting functions with the pragma {.locks: "unknown".} to make their type compatible with that of the standard sort function.
if n<2 then
return x -- already sorted (trivial case)
end if
mid = floor((n+1)/2)
midval = x[mid]
x[mid] = x[1]
midn = 1
for i=2 to n do
xi = x[i]
c = compare(xi,midval)
if c<0 then
left &= xi
elsif c>0 then
right &= xi
else
midn += 1
end if
end for
return quick_sort2(left) & repeat(midval,midn) & quick_sort2(right)
end function
 
We have also added the array as first parameter of the internal function “sorter” as Nim compiler doesn’t allow direct access to this mutable array in function “quicksort” (memory safety violation).
function quick_sort(sequence s)
sequence qstack
integer first, last, stackptr, I, J, tmp, pivot
 
<syntaxhighlight lang="nim">import algorithm
qstack = repeat(0,floor((length(s)/5)+10)) -- create a stack
import random
import sequtils
import times
 
first = 1
last = length(s)
stackptr = 0
while 1 do
while first<last do
pivot = s[floor(last+first)/2]
I = first
J = last
while 1 do
while s[I]<pivot do
I += 1
end while
while s[J]>pivot do
J -= 1
end while
if I>J then exit end if
if I<J then
tmp = s[I]
s[I] = s[J]
s[J] = tmp
end if
I += 1
J -= 1
if I>J then exit end if
end while
if I<last then
qstack[stackptr+1] = I
qstack[stackptr+2] = last
stackptr += 2
end if
last = J
end while
if stackptr=0 then exit end if
stackptr -= 2
first = qstack[stackptr+1]
last = qstack[stackptr+2]
end while
return s
end function
 
####################################################################################################
function radixSortn(sequence s, integer n)
# Data.
sequence buckets = repeat({},10)
sequence res = {}
for i=1 to length(s) do
integer digit = remainder(floor(s[i]/power(10,n-1)),10)+1
buckets[digit] = append(buckets[digit],s[i])
end for
for i=1 to length(buckets) do
integer len = length(buckets[i])
if len!=0 then
if len=1 or n=1 then
res &= buckets[i]
else
res &= radixSortn(buckets[i],n-1)
end if
end if
end for
return res
end function
 
proc oneSeq(n: int): seq[int] = repeat(1, n)
function split_by_sign(sequence s)
sequence buckets = {{},{}}
for i=1 to length(s) do
integer si = s[i]
if si<0 then
buckets[1] = append(buckets[1],-si)
else
buckets[2] = append(buckets[2],si)
end if
end for
return buckets
end function
 
#---------------------------------------------------------------------------------------------------
function radix_sort(sequence s)
integer mins = min(s)
integer passes = max(max(s),abs(mins))
passes = floor(log10(passes))+1
if mins<0 then
sequence buckets = split_by_sign(s)
buckets[1] = reverse(sq_uminus(radixSortn(buckets[1],passes)))
buckets[2] = radixSortn(buckets[2],passes)
s = buckets[1]&buckets[2]
else
s = radixSortn(s,passes)
end if
return s
end function
 
proc shuffledSeq(n: int): seq[int] =
function shell_sort(sequence s)
result.setLen(n)
integer gap = floor(length(s)/2), j
for item in result.mitems: item = rand(1..(10 * n))
object temp
while gap>0 do
for i=gap to length(s) do
temp = s[i]
j = i-gap
while j>=1 and temp<=s[j] do
s[j+gap] = s[j]
j -= gap
end while
s[j+gap] = temp
end for
gap = floor(gap/2)
end while
return s
end function
 
#---------------------------------------------------------------------------------------------------
function shell_sort2(sequence x)
integer gap, j, first, last
object xi, xj
 
proc ascendingSeq(n: int): seq[int] = sorted(shuffledSeq(n))
last = length(x)
gap = floor(last/10)+1
while TRUE do
first = gap+1
for i=first to last do
xi = x[i]
j = i-gap
while TRUE do
xj = x[j]
if xi>=xj then
j += gap
exit
end if
x[j+gap] = xj
if j<=gap then
exit
end if
j -= gap
end while
x[j] = xi
end for
if gap=1 then
return x
else
gap = floor(gap/3.5)+1
end if
end while
end function
 
function siftDown(sequence arr, integer s, integer last)
integer root = s
while root*2<=last do
integer child = root*2
if child<last and arr[child]<arr[child+1] then
child += 1
end if
if arr[root]>=arr[child] then exit end if
object tmp = arr[root]
arr[root] = arr[child]
arr[child] = tmp
root = child
end while
return arr
end function
 
####################################################################################################
function heapify(sequence arr, integer count)
# Algorithms.
integer s = floor(count/2)
while s>0 do
arr = siftDown(arr,s,count)
s -= 1
end while
return arr
end function
 
func bubbleSort(a: var openArray[int]) {.locks: "unknown".} =
function heap_sort(sequence arr)
var n = a.len
integer last = length(arr)
while true:
arr = heapify(arr,last)
whilevar last>1n2 do= 0
for i in object tmp = arr[1]..<n:
if arra[i - 1] => arra[lasti]:
arrswap a[lasti], =a[i tmp- 1]
lastn2 -= 1i
arrn = siftDown(arr,1,last)n2
endif whilen == 0: break
return arr
end function
 
#---------------------------------------------------------------------------------------------------
include builtins/sort.e
 
func insertionSort(a: var openArray[int]) {.locks: "unknown".} =
enum ONES = 1, SORTED = 2, RANDOM = 3, REVERSE = 4
for index in 1..a.high:
let value = a[index]
var subIndex = index - 1
while subIndex >= 0 and a[subIndex] > value:
a[subIndex + 1] = a[subIndex]
dec subIndex
a[subIndex + 1] = value
 
#---------------------------------------------------------------------------------------------------
constant tabtitles = {"ones","sorted","random","reverse"}
integer tabidx = 3
 
func quickSort(a: var openArray[int]) {.locks: "unknown".} =
integer STEP
 
func sorter(a: var openArray[int]; first, last: int) =
function tr(sequence name, integer rid=routine_id(name))
if last - first < 1: return
return {name,rid}
let pivot = a[first + (last - first) div 2]
end function
var left = first
var right = last
while left <= right:
while a[left] < pivot: inc left
while a[right] > pivot: dec right
if left <= right:
swap a[left], a[right]
inc left
dec right
if first < right: a.sorter(first, right)
if left < last: a.sorter(left, last)
 
a.sorter(0, a.high)
constant tests = {tr("quick_sort"),
tr("quick_sort2"),
tr("radix_sort"),
tr("shell_sort"),
tr("shell_sort2"),
tr("heap_sort"),
tr("sort"), -- builtin
}
 
#---------------------------------------------------------------------------------------------------
sequence results = repeat(repeat({}, length(tests)),length(tabtitles))
 
func radixSort(a: var openArray[int]) {.locks: "unknown".} =
sequence dsdx = repeat(repeat(0,length(tests)),length(tabtitles))
 
var tmp = newSeq[int](a.len)
integer ds_index
 
for shift in countdown(63, 0):
function idle_action_cb()
for item in tmp.mitems: item = 0
atom best = -1, -- fastest last
var bestij = 0, -- 1..length(tests)
for bestti =in 0, -- 1..length(tabtitles)a.high:
let move = a[i] shl shift >= 0
len
let toBeMoved = if shift == 0: not move else: move
sequence todo
-- if toBeMoved:
tmp[j] = a[i]
-- Search for something to do, active/visible tab first.
inc j
-- Any result set of length 0 -> just do one.
else:
-- Of all result sets<8, pick the lowest [$].
a[i -- j] = a[i]
for i in j..tmp.high: tmp[i] = a[i - j]
todo = {tabidx}
for t=1i toin length(tabtitles)0..a.high: a[i] = dotmp[i]
if t!=tabidx then todo &= t end if
end for
 
#---------------------------------------------------------------------------------------------------
for t=1 to length(tabtitles) do
integer ti = todo[t]
for i=1 to length(results[ti]) do
len = length(results[ti][i])
if len=0 then
best = 0
besti = i
bestt = ti
exit
elsif len<8 then
if (best=-1) or (best>results[ti][i][$]) then
best = results[ti][i][$]
besti = i
bestt = ti
end if
end if
end for
if (t=1) and (besti!=0) then exit end if
end for
if best>10 then
-- cop out if it is getting too slow
besti = 0
end if
if besti!=0 then
STEP = iff(not XQS and bestt=ONES?1000:100000)
len = (length(results[bestt][besti])+1)*STEP
sequence test = iff(bestt=ONES?repeat(1,len):
iff(bestt=SORTED?tagset(len):
iff(bestt=RANDOM?shuffle(tagset(len)):
iff(bestt=REVERSE?reverse(tagset(len)):9/0))))
ds_index = dsdx[bestt][besti]
atom t0 = time()
sequence check = call_func(tests[besti][2],{test})
t0 = time()-t0
-- if check!=sort(test) then ?9/0 end if
plot = plots[bestt]
IupPlotInsert(plot, ds_index, -1, len, t0)
results[bestt][besti] = append(results[bestt][besti],t0)
IupSetAttribute(plot,"REDRAW",NULL)
sequence progress = {bestt}
for i=1 to length(results[bestt]) do
progress &= length(results[bestt][i])
end for
IupSetStrAttribute(dlg,"TITLE","Compare sorting algorithms %s",{sprint(progress)})
return IUP_CONTINUE
end if
IupSetAttribute(dlg,"TITLE","Compare sorting algorithms (all done, idle)")
return IUP_IGNORE -- all done, remove callback
end function
constant cb_idle_action = Icallback("idle_action_cb")
 
func shellSort(a: var openArray[int]) {.locks: "unknown".} =
function tabchange_cb(Ihandle /*self*/, Ihandle /*new_tab*/)
tabidx = IupGetInt(tabs,"VALUEPOS")+1
plot = plots[tabidx]
return IUP_DEFAULT;
end function
 
const Gaps = [701, 301, 132, 57, 23, 10, 4, 1]
function esc_close(Ihandle /*ih*/, atom c)
if c=K_ESC then return IUP_CLOSE end if
return IUP_CONTINUE
end function
 
for gap in Gaps:
procedure main()
for i in gap..a.high:
IupOpen()
let temp = a[i]
var j = i
while j >= gap and a[j - gap] > temp:
a[j] = a[j - gap]
dec j, gap
a[j] = temp
 
#---------------------------------------------------------------------------------------------------
plots = {}
for i=1 to length(tabtitles) do
if XQS then
-- results[ONES][1] = repeat(0,8)
results[ONES][4] = repeat(0,8)
end if
plot = IupPlot()
IupSetAttribute(plot,"MENUITEMPROPERTIES","YES")
IupSetAttribute(plot,"TABTITLE",tabtitles[i])
IupSetAttribute(plot,"GRID","YES")
IupSetAttribute(plot,"MARGINLEFT","50")
IupSetAttribute(plot,"MARGINBOTTOM","40")
IupSetAttribute(plot,"LEGEND","YES")
IupSetAttribute(plot,"LEGENDPOS","TOPLEFT")
-- IupSetAttribute(plot,"AXS_YSCALE","LOG10")
-- IupSetAttribute(plot,"AXS_XSCALE","LOG10")
for j=1 to length(tests) do
IupPlotBegin(plot)
dsdx[i][j] = IupPlotEnd(plot)
IupSetAttribute(plot,"DS_NAME",tests[j][1])
end for
plots = append(plots,plot)
end for
tabs = IupTabs(plots)
IupSetCallback(tabs, "TABCHANGE_CB", Icallback("tabchange_cb"))
dlg = IupDialog(tabs)
IupSetAttributes(dlg, "RASTERSIZE=%dx%d", {640, 480})
IupSetAttribute(dlg, "TITLE", "Compare sorting algorithms")
IupSetCallback(dlg, "K_ANY", Icallback("esc_close"))
IupShow(dlg)
IupSetInt(tabs, "VALUEPOS", tabidx-1)
IupSetGlobalFunction("IDLE_ACTION", cb_idle_action)
IupMainLoop()
IupClose()
end procedure
 
func standardSort(a: var openArray[int]) =
main()</lang>
a.sort()
 
 
####################################################################################################
# Main code.
 
import strformat
 
const
 
Runs = 10
Lengths = [1, 10, 100, 1_000, 10_000, 100_000]
 
Sorts = [bubbleSort, insertionSort, quickSort, radixSort, shellSort, standardSort]
 
const
SortTitles = ["Bubble", "Insert", "Quick ", "Radix ", "Shell ", "Standard"]
SeqTitles = ["All Ones", "Ascending", "Shuffled"]
 
var totals: array[SeqTitles.len, array[Sorts.len, array[Lengths.len, Duration]]]
 
randomize()
 
for k, n in Lengths:
let seqs = [oneSeq(n), ascendingSeq(n), shuffledSeq(n)]
for _ in 1..Runs:
for i, s in seqs:
for j, sort in Sorts:
var s = s
let t0 = getTime()
s.sort()
totals[i][j][k] += getTime() - t0
 
echo "All timings in microseconds\n"
stdout.write "Sequence length "
for length in Lengths:
stdout.write &"{length:6d} "
echo '\n'
for i in 0..SeqTitles.high:
echo &" {SeqTitles[i]}:"
for j in 0..Sorts.high:
stdout.write &" {SortTitles[j]:8s} "
for k in 0..Lengths.high:
let time = totals[i][j][k].inMicroseconds div Runs
stdout.write &"{time:8d} "
echo ""
echo '\n'</syntaxhighlight>
 
{{out}}
<pre>All timings in microseconds
 
Sequence length 1 10 100 1000 10000 100000
 
All Ones:
Bubble 0 0 0 0 6 64
Insert 0 0 0 1 9 90
Quick 0 0 3 9 105 1201
Radix 1 4 34 103 848 8354
Shell 0 0 2 10 97 946
Standard 0 2 2 6 45 380
 
 
Ascending:
Bubble 0 0 0 0 6 61
Insert 0 0 0 1 9 94
Quick 0 0 3 11 88 919
Radix 1 5 47 154 1435 15519
Shell 0 0 2 10 95 954
Standard 0 0 2 7 47 463
 
 
Shuffled:
Bubble 0 0 38 1026 133729 16181412
Insert 0 0 8 152 10010 1133210
Quick 0 0 9 63 607 7199
Radix 1 5 46 157 1405 15557
Shell 0 0 8 69 708 10236
Standard 0 0 18 96 992 12394</pre>
 
===Conclusions===
 
Compared to the results obtained by the Kotlin program, the radix sort seems less efficient and the shell sort more efficient. Maybe some optimizations could improve the radix sort, but it seems also that the shell sort is well optimized by the Nim compiler and the C compiler.
 
The standard sort behaves well if the list is already sorted. For random list, it is less efficient than the quick sort or the shell sort, but is still a good performer.
 
=={{header|Phix}}==
{{libheader|Phix/pGUI}}
<!--<syntaxhighlight lang="phix">-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Compare_sorting_algorithms.exw</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">XQS</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">01</span> <span style="color: #000080;font-style:italic;">-- (set to 1 to exclude quick_sort and shell_sort from ones)</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tabs</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">plot</span>
<span style="color: #004080;">Ihandles</span> <span style="color: #000000;">plots</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">quick_sort2</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">x</span> <span style="color: #000080;font-style:italic;">-- already sorted (trivial case)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">mid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">midn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">midval</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">mid</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">left</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">right</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">mid</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">xi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">midval</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">left</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">left</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xi</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">right</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">right</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xi</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">midn</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">quick_sort2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">left</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">&</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">midval</span><span style="color: #0000FF;">,</span><span style="color: #000000;">midn</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">quick_sort2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">right</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">quick_sort</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">qstack</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">10</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- create a stack</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">first</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">stackptr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">first</span><span style="color: #0000FF;"><</span><span style="color: #000000;">last</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">pivot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">last</span><span style="color: #0000FF;">+</span><span style="color: #000000;">first</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">si</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">sj</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">I</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">first</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">J</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">last</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">I</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">si</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">pivot</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">I</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">sj</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">J</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">sj</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">pivot</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">J</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">I</span><span style="color: #0000FF;">></span><span style="color: #000000;">J</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">I</span><span style="color: #0000FF;"><</span><span style="color: #000000;">J</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">si</span><span style="color: #0000FF;">=</span><span style="color: #000000;">sj</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">I</span><span style="color: #0000FF;">,</span><span style="color: #000000;">J</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">J</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">I</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">I</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sj</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">J</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">si</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">I</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">J</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">I</span><span style="color: #0000FF;">></span><span style="color: #000000;">J</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">I</span><span style="color: #0000FF;"><</span><span style="color: #000000;">last</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">qstack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">stackptr</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">I</span>
<span style="color: #000000;">qstack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">stackptr</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">last</span>
<span style="color: #000000;">stackptr</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">J</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">stackptr</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">stackptr</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">2</span>
<span style="color: #000000;">first</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">qstack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">stackptr</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">qstack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">stackptr</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">radixSortn</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">buckets</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]/</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">],</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">radixSortn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">split_by_sign</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">buckets</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{},{}}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">si</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],-</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">buckets</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">radix_sort</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- NB this is an integer-only sort</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">mins</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">passes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">log10</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mins</span><span style="color: #0000FF;">))))+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">mins</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">buckets</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">split_by_sign</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sq_uminus</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radixSortn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">passes</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">radixSortn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">passes</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">buckets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">radixSortn</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">passes</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">shell_sort</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">gap</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">gap</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">gap</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">temp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">gap</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">temp</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">gap</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">j</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">gap</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">gap</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">temp</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">gap</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gap</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">shell_sort2</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">gap</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">last</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">TRUE</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">first</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">gap</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">first</span> <span style="color: #008080;">to</span> <span style="color: #000000;">last</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">xi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">gap</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">TRUE</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">xj</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">xi</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">xj</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">j</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">gap</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">gap</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xj</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">gap</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">j</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">gap</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">x</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xi</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">gap</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">x</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">gap</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gap</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3.5</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">siftDown</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">last</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">root</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">root</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">last</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">child</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">root</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">child</span><span style="color: #0000FF;"><</span><span style="color: #000000;">last</span> <span style="color: #008080;">and</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">]<</span><span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">child</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">root</span><span style="color: #0000FF;">]>=</span><span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">tmp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">root</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">root</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">child</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tmp</span>
<span style="color: #000000;">root</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">child</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">arr</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">heapify</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">count</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">arr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">siftDown</span><span style="color: #0000FF;">(</span><span style="color: #000000;">arr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">arr</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">heap_sort</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">arr</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">arr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">heapify</span><span style="color: #0000FF;">(</span><span style="color: #000000;">arr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">last</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">last</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">tmp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">last</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">arr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">last</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tmp</span>
<span style="color: #000000;">last</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">arr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">siftDown</span><span style="color: #0000FF;">(</span><span style="color: #000000;">arr</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">last</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">arr</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">sort</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">ONES</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">SORTED</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">RANDOM</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">REVERSE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">4</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tabtitles</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"ones"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"sorted"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"random"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"reverse"</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">tabidx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">STEP</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">rid</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #000000;">name</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rid</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"quick_sort"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"quick_sort2"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"radix_sort"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"shell_sort"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"shell_sort2"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"heap_sort"</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">tr</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"sort"</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- builtin</span>
<span style="color: #0000FF;">}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">results</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({},</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabtitles</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">dsdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabtitles</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ds_index</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">idle_action_cb</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">best</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- fastest last</span>
<span style="color: #000000;">besti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 1..length(tests) </span>
<span style="color: #000000;">bestt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- 1..length(tabtitles)</span>
<span style="color: #000000;">len</span>
<span style="color: #000080;font-style:italic;">--
-- Search for something to do, active/visible tab first.
-- Any result set of length 0 -&gt; just do one.
-- Of all result sets&lt;8, pick the lowest [$].
--</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">todo</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">tabidx</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabtitles</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">tabidx</span> <span style="color: #008080;">then</span> <span style="color: #000000;">todo</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">t</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabtitles</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">todo</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">best</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">besti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #000000;">bestt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ti</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">len</span><span style="color: #0000FF;"><</span><span style="color: #000000;">8</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">best</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">best</span><span style="color: #0000FF;">></span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][$])</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">best</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][$]</span>
<span style="color: #000000;">besti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #000000;">bestt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ti</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">besti</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">best</span><span style="color: #0000FF;">></span><span style="color: #000000;">10</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- cop out if it is getting too slow</span>
<span style="color: #000000;">besti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">besti</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">STEP</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #008080;">not</span> <span style="color: #000000;">XQS</span> <span style="color: #008080;">and</span> <span style="color: #000000;">bestt</span><span style="color: #0000FF;">=</span><span style="color: #000000;">ONES</span><span style="color: #0000FF;">?</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">:</span><span style="color: #000000;">100000</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">][</span><span style="color: #000000;">besti</span><span style="color: #0000FF;">])+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">STEP</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">=</span><span style="color: #000000;">ONES</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">len</span><span style="color: #0000FF;">):</span>
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SORTED</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len</span><span style="color: #0000FF;">):</span>
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">=</span><span style="color: #000000;">RANDOM</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">shuffle</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)):</span>
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">=</span><span style="color: #000000;">REVERSE</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)):</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))))</span>
<span style="color: #000000;">ds_index</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dsdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">][</span><span style="color: #000000;">besti</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">check</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">call_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">besti</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">test</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span>
<span style="color: #000080;font-style:italic;">-- if check!=sort(test) then ?9/0 end if</span>
<span style="color: #000000;">plot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">plots</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">IupPlotInsert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ds_index</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">][</span><span style="color: #000000;">besti</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">][</span><span style="color: #000000;">besti</span><span style="color: #0000FF;">],</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"REDRAW"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #7060A8;">progress</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">progress</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bestt</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Compare sorting algorithms %s"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">progress</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Compare sorting algorithms (all done, idle)"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span> <span style="color: #000080;font-style:italic;">-- all done, remove callback</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">cb_idle_action</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"idle_action_cb"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">tabchange_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*self*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*new_tab*/</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">tabidx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabs</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"VALUEPOS"</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">plot</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">plots</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tabidx</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span><span style="color: #0000FF;">;</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">plots</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabtitles</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">XQS</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- results[ONES][1] = repeat(0,8)</span>
<span style="color: #000000;">results</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ONES</span><span style="color: #0000FF;">][</span><span style="color: #000000;">4</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">plot</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupPlot</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"MENUITEMPROPERTIES"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"YES"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TABTITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tabtitles</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"GRID"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"YES"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"MARGINLEFT"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"50"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"MARGINBOTTOM"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"40"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"LEGEND"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"YES"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"LEGENDPOS"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TOPLEFT"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- IupSetAttribute(plot,"AXS_YSCALE","LOG10")
-- IupSetAttribute(plot,"AXS_XSCALE","LOG10")</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">IupPlotBegin</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dsdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupPlotEnd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DS_NAME"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">plots</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plots</span><span style="color: #0000FF;">,</span><span style="color: #000000;">plot</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">tabs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTabs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plots</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabs</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"TABCHANGE_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"tabchange_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabs</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE=800x480"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Compare sorting algorithms"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tabs</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"VALUEPOS"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tabidx</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetGlobalFunction</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"IDLE_ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cb_idle_action</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
===Conclusions===
I knew bubblesort and insertion sort would be bad, but nonot so bad that you cannot meaningfully plot them against better sorts.
(logarithmic scale helps, but is still not enough)
I had no idea that (these particular implementations of) quicksort and shellsort would be so bad on a sequence of all 1s.
Line 2,033 ⟶ 3,026:
{{works with|Python|2.5}}
===Examples of sorting routines===
<langsyntaxhighlight lang="python">def builtinsort(x):
x.sort()
 
Line 2,051 ⟶ 3,044:
if size < 2: return seq
low, middle, up = partition(seq, random.choice(seq))
return qsortranpart(low) + middle + qsortranpart(up)</langsyntaxhighlight>
 
===Sequence generators===
 
<langsyntaxhighlight lang="python">def ones(n):
return [1]*n
 
Line 2,064 ⟶ 3,057:
x = range(n)
random.shuffle(x)
return x</langsyntaxhighlight>
===Write timings===
<langsyntaxhighlight lang="python">def write_timings(npoints=10, maxN=10**4, sort_functions=(builtinsort,insertion_sort, qsort),
sequence_creators = (ones, range, shuffledrange)):
Ns = range(2, maxN, maxN//npoints)
Line 2,072 ⟶ 3,065:
for make_seq in sequence_creators:
Ts = [usec(sort, (make_seq(n),)) for n in Ns]
writedat('%s-%s-%d-%d.xy' % (sort.__name__, make_seq.__name__, len(Ns), max(Ns)), Ns, Ts)</langsyntaxhighlight>
Where ''writedat()'' is defined in the [[Write float arrays to a text file]], ''usec()'' - [[Query Performance]], ''insertion_sort()'' - [[Insertion sort]], ''qsort'' - [[Quicksort]] subtasks, correspondingly.
 
Line 2,078 ⟶ 3,071:
{{libheader|matplotlib}}
{{libheader|NumPy}}
<langsyntaxhighlight lang="python">import operator
import numpy, pylab
def plotdd(dictplotdict):
Line 2,100 ⟶ 3,093:
pylab.savefig(figname+'.png')
pylab.savefig(figname+'.pdf')
print figname</langsyntaxhighlight>
See [[Plot x, y arrays]] and [[Polynomial Fitting]] subtasks for a basic usage of ''pylab.plot()'' and ''numpy.polyfit()''.
 
<langsyntaxhighlight lang="python">import collections, itertools, glob, re
import numpy
def plot_timings():
Line 2,132 ⟶ 3,125:
# actual plotting
plotdd(df)
plotdd(ds) # see ``plotdd()`` above</langsyntaxhighlight>
 
===Figures: log2( time in microseconds ) vs. log2( sequence length )===
Line 2,138 ⟶ 3,131:
[[File:Range.png|300px|thumb|right|log(Time) vs. log(N): Relative performance on range(N) as an input]]
[[File:Shuffledrange.png|300px|thumb|right|log(Time) vs. log(N): Relative performance on random permutation of range(N) as an input]]
<langsyntaxhighlight lang="python">sort_functions = [
builtinsort, # see implementation above
insertion_sort, # see [[Insertion sort]]
Line 2,155 ⟶ 3,148:
sort_functions=sort_functions,
sequence_creators = (ones, range, shuffledrange))
plot_timings()</langsyntaxhighlight>
Executing above script we get belowed figures.
====ones====
Line 2,178 ⟶ 3,171:
qsort - O(N*log(N))
qsortranpart - O(N) ???
 
=={{header|Raku}}==
{{trans|Julia}}
<syntaxhighlight lang="raku" line># 20221114 Raku programming solution
 
my ($rounds,$size) = 3, 2000;
my @allones = 1 xx $size;
my @sequential = 1 .. $size;
my @randomized = @sequential.roll xx $size;
 
sub insertion_sort ( @a is copy ) { # rosettacode.org/wiki/Sorting_algorithms/Insertion_sort#Raku
for 1 .. @a.end -> \k {
loop (my ($j,\value)=k-1,@a[k];$j>-1&&@a[$j]>value;$j--) {@a[$j+1]=@a[$j]}
@a[$j+1] = value;
}
return @a;
}
 
sub merge_sort ( @a ) { # rosettacode.org/wiki/Sorting_algorithms/Merge_sort#Raku
return @a if @a <= 1;
 
my $m = @a.elems div 2;
my @l = merge_sort @a[ 0 ..^ $m ];
my @r = merge_sort @a[ $m ..^ @a ];
 
return flat @l, @r if @l[*-1] !after @r[0];
return flat gather {
take @l[0] before @r[0] ?? @l.shift !! @r.shift
while @l and @r;
take @l, @r;
}
}
 
sub quick-sort(@data) { # andrewshitov.com/2019/06/23/101-quick-sort-in-perl-6/
return @data if @data.elems <= 1;
 
my ($pivot,@left, @right) = @data[0];
 
for @data[1..*] -> $x { $x < $pivot ?? push @left, $x !! push @right, $x }
 
return flat(quick-sort(@left), $pivot, quick-sort(@right));
}
 
sub comparesorts($rounds, @tosort) {
my ( $iavg, $mavg, $qavg, $t );
 
for (<i m q> xx $rounds).flat.pick(*) -> \sort_type {
given sort_type {
when 'i' { $t = now ; insertion_sort @tosort ; $iavg += now - $t }
when 'm' { $t = now ; merge_sort @tosort ; $mavg += now - $t }
when 'q' { $t = now ; quick-sort @tosort ; $qavg += now - $t }
}
}
return $iavg, $mavg, $qavg »/» $rounds
}
 
for <ones presorted randomized>Z(@allones,@sequential,@randomized) -> ($t,@d) {
say "Average sort times for $size $t:";
{ say "\tinsertion sort\t$_[0]\n\tmerge sort\t$_[1]\n\tquick sort\t$_[2]" }(comparesorts $rounds,@d)
}</syntaxhighlight>
{{out}}
<pre>Average sort times for 2000 ones:
insertion sort 0.112333083
merge sort 0.506624066
quick sort 5.899009606666667
Average sort times for 2000 presorted:
insertion sort 0.03596163
merge sort 0.474839352
quick sort 5.896118350666666
Average sort times for 2000 randomized:
insertion sort 5.352926729
merge sort 0.784896982
quick sort 0.11422247299999999</pre>
 
=={{header|REXX}}==
One goal for this REXX program was to include as many different sorts (that sorted arrays and not lists).
 
Because of the disparencies of some sorting algorithms, &nbsp; the range of numbers was chosen to be &nbsp; '''5''' &nbsp; so that the
<br>slower sorts wouldn't consume a lot of time trying to sort larger arrays.
 
The number of ranges can be increased at the expense of a wider display of output.
<syntaxhighlight lang="rexx">/*REXX pgm compares various sorts for 3 types of input sequences: ones/ascending/random.*/
parse arg ranges start# seed . /*obtain optional arguments from the CL*/
if ranges=='' | ranges=="," then ranges= 5 /*Not Specified? Then use the default.*/
if start#=='' | start#=="," then start#= 250 /* " " " " " " */
if seed=='' | seed=="," then seed= 1946 /*use a repeatable seed for RANDOM BIF*/
if datatype(seed, 'W') then call random ,,seed /*Specified? Then use as a RANDOM seed*/
kinds= 3; hdr=; #= start# /*hardcoded/fixed number of datum kinds*/
do ra=1 for ranges
hdr= hdr || center( commas(#) "numbers", 25)'│' /*(top) header for the output title.*/
do ki=1 for kinds
call gen@@ #, ki
call set@; call time 'R'; call bubble #; bubble.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call cocktail #; cocktail.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call cocktailSB #; cocktailSB.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call comb #; comb.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call exchange #; exchange.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call gnome #; gnome.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call heap #; heap.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call insertion #; insertion.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call merge #; merge.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call pancake #; pancake.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call quick #; quick.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call radix #; radix.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call selection #; selection.ra.ki= format(time("E"),,2)
call set@; call time 'R'; call shell #; shell.ra.ki= format(time("E"),,2)
end /*ki*/
#= # + # /*double # elements.*/
end /*ra*/
say; say; say /*say blank sep line*/
say center(' ', 11 ) "│"left(hdr, length(hdr)-1)"│" /*replace last char.*/
reps= ' allONES ascend random │' /*build a title bar.*/
xreps= copies( center(reps, length(reps)), ranges) /*replicate ranges. */
creps= left(xreps, length(xreps)-1)"│" /*replace last char.*/
say center('sort type', 11 ) "│"creps; Lr= length(reps)
xcreps= copies( left('', Lr-1, '─')"┼", ranges)
say center('' , 12, '─')"┼"left(xcreps, length(xcreps)-1)"┤"
call show 'bubble' /* ◄──── show results for bubble sort.*/
call show 'cocktail' /* ◄──── " " " cocktail " */
call show 'cocktailSB' /*+Shifting Bounds*/ /* ◄──── " " " cocktailSB " */
call show 'comb' /* ◄──── " " " comb " */
call show 'exchange' /* ◄──── " " " exchange " */
call show 'gnome' /* ◄──── " " " gnome " */
call show 'heap' /* ◄──── " " " heap " */
call show 'insertion' /* ◄──── " " " insertion " */
call show 'merge' /* ◄──── " " " merge " */
call show 'pancake' /* ◄──── " " " pancake " */
call show 'quick' /* ◄──── " " " quick " */
call show 'radix' /* ◄──── " " " radix " */
call show 'selection' /* ◄──── " " " shell " */
call show 'shell' /* ◄──── " " " shell " */
say translate(center('' , 12, '─')"┴"left(xcreps, length(xcreps)-1)"┘", '┴', "┼")
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
inOrder: parse arg n; do j=1 for n-1; k= j+1; if @.j>@.k then return 0; end; return 1
set@: @.=; do a=1 for #; @.a= @@.a; end; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
gen@@: procedure expose @@.; parse arg n,kind; nn= min(n, 100000) /*1e5≡REXX's max.*/
do j=1 for nn; select
when kind==1 then @@.j= 1 /*all ones. */
when kind==2 then @@.j= j /*ascending.*/
when kind==3 then @@.j= random(, nn) /*random. */
end /*select*/
end /*j*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: parse arg aa; _= left(aa, 11) "│"
do ra=1 for ranges
do ki=1 for kinds
_= _ right( value(aa || . || ra || . || ki), 7, ' ')
end /*k*/
_= _ "│"
end /*r*/; say _; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
bubble: procedure expose @.; parse arg n /*N: is the number of @ elements. */
do m=n-1 by -1 until ok; ok=1 /*keep sorting @ array until done.*/
do j=1 for m; k=j+1; if @.j<=@.k then iterate /*elements in order? */
_=@.j; @.j=@.k; @.k=_; ok=0 /*swap 2 elements; flag as not done.*/
end /*j*/
end /*m*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
cocktail: procedure expose @.; parse arg N; nn= N-1 /*N: is number of items. */
do until done; done= 1
do j=1 for nn; jp= j+1
if @.j>@.jp then do; done=0; _=@.j; @.j=@.jp; @.jp=_; end
end /*j*/
if done then leave /*No swaps done? Finished.*/
do k=nn for nn by -1; kp= k+1
if @.k>@.kp then do; done=0; _=@.k; @.k=@.kp; @.kp=_; end
end /*k*/
end /*until*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
cocktailsb: procedure expose @.; parse arg N /*N: is number of items. */
end$= N - 1; beg$= 1
do while beg$ <= end$
beg$$= end$; end$$= beg$
do j=beg$ to end$; jp= j + 1
if @.j>@.jp then do; _=@.j; @.j=@.jp; @.jp=_; end$$=j; end
end /*j*/
end$= end$$ - 1
do k=end$ to beg$ by -1; kp= k + 1
if @.k>@.kp then do; _=@.k; @.k=@.kp; @.kp=_; beg$$=k; end
end /*k*/
beg$= beg$$ + 1
end /*while*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
comb: procedure expose @.; parse arg n /*N: is the number of @ elements. */
g= n-1 /*G: is the gap between the sort COMBs*/
do until g<=1 & done; done= 1 /*assume sort is done (so far). */
g= g * 0.8 % 1 /*equivalent to: g= trunc( g / 1.25) */
if g==0 then g= 1 /*handle case of the gap is too small. */
do j=1 until $>=n; $= j + g /*$: a temporary index (pointer). */
if @.j>@.$ then do; _= @.j; @.j= @.$; @.$= _; done= 0; end
end /*j*/ /* [↑] swap two elements in the array.*/
end /*until*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
exchange: procedure expose @.; parse arg n 1 h /*both N and H have the array size.*/
do while h>1; h= h % 2
do i=1 for n-h; j= i; k= h+i
do while @.k<@.j
_= @.j; @.j= @.k; @.k= _; if h>=j then leave; j= j-h; k= k-h
end /*while @.k<@.j*/
end /*i*/
end /*while h>1*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
gnome: procedure expose @.; parse arg n; k= 2 /*N: is number items. */
do j=3 while k<=n; p= k - 1 /*P: is previous item.*/
if @.p<<=@.k then do; k= j; iterate; end /*order is OK so far. */
_= @.p; @.p= @.k; @.k= _ /*swap two @ entries. */
k= k - 1; if k==1 then k= j; else j= j-1 /*test for 1st index. */
end /*j*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
heap: procedure expose @.; arg n; do j=n%2 by -1 to 1; call heapS j,n; end /*j*/
do n=n by -1 to 2; _= @.1; @.1= @.n; @.n= _; call heapS 1,n-1
end /*n*/; return /* [↑] swap two elements; and shuffle.*/
 
heapS: procedure expose @.; parse arg i,n; $= @.i /*obtain parent.*/
do while i+i<=n; j= i+i; k= j+1; if k<=n then if @.k>@.j then j= k
if $>=@.j then leave; @.i= @.j; i= j
end /*while*/; @.i= $; return /*define lowest.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
insertion: procedure expose @.; parse arg n
do i=2 to n; $= @.i; do j=i-1 by -1 to 1 while @.j>$
_= j + 1; @._= @.j
end /*j*/
_= j + 1; @._= $
end /*i*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
merge: procedure expose @. !.; parse arg n, L; if L=='' then do; !.=; L= 1; end
if n==1 then return; h= L + 1
if n==2 then do; if @.L>@.h then do; _=@.h; @.h=@.L; @.L=_; end; return; end
m= n % 2 /* [↑] handle case of two items.*/
call merge n-m, L+m /*divide items to the left ···*/
call merger m, L, 1 /* " " " " right ···*/
i= 1; j= L + m
do k=L while k<j /*whilst items on right exist ···*/
if j==L+n | !.i<=@.j then do; @.k= !.i; i= i + 1; end
else do; @.k= @.j; j= j + 1; end
end /*k*/; return
 
merger: procedure expose @. !.; parse arg n,L,T
if n==1 then do; !.T= @.L; return; end
if n==2 then do; h= L + 1; q= T + 1; !.q= @.L; !.T= @.h; return; end
m= n % 2 /* [↑] handle case of two items.*/
call merge m, L /*divide items to the left ···*/
call merger n-m, L+m, m+T /* " " " " right ···*/
i= L; j= m + T
do k=T while k<j /*whilst items on left exist ···*/
if j==T+n | @.i<=!.j then do; !.k= @.i; i= i + 1; end
else do; !.k= !.j; j= j + 1; end
end /*k*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
pancake: procedure expose @.; parse arg n .; if inOrder(n) then return
do n=n by -1 for n-1
!= @.1; ?= 1; do j=2 to n; if @.j<=! then iterate
!= @.j; ?= j
end /*j*/
call panFlip ?; call panFlip n
end /*n*/; return
 
panFlip: parse arg y; do i=1 for (y+1)%2; yi=y-i+1; _=@.i; @.i=@.yi; @.yi=_; end; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
quick: procedure expose @.; a.1=1; parse arg b.1; $= 1 /*access @.; get #; define pivot.*/
if inOrder(b.1) then return
do while $\==0; L= a.$; t= b.$; $= $-1; if t<2 then iterate
H= L+t-1; ?= L+t%2
if @.H<@.L then if @.?<@.H then do; p=@.H; @.H=@.L; end
else if @.?>@.L then p=@.L
else do; p=@.?; @.?=@.L; end
else if @.?<@.L then p=@.L
else if @.?>@.H then do; p=@.H; @.H=@.L; end
else do; p=@.?; @.?=@.L; end
j= L+1; k=h
do forever
do j=j while j<k & @.j<=p; end /*a tinie─tiny loop.*/
do k=k by -1 while j<k & @.k>=p; end /*another " " */
if j>=k then leave /*segment finished? */
_= @.j; @.j= @.k; @.k= _ /*swap J&K elements.*/
end /*forever*/
$= $+1; k= j-1; @.L= @.k; @.k= p
if j<=? then do; a.$= j; b.$= H-j+1; $= $+1; a.$= L; b.$= k-L; end
else do; a.$= L; b.$= k-L; $= $+1; a.$= j; b.$= H-j+1; end
end /*while $¬==0*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
radix: procedure expose @.; parse arg size,w; mote= c2d(' '); #= 1; !.#._n= size
!.#._b= 1; if w=='' then w= 8
!.#._i= 1; do i=1 for size; y=@.i; @.i= right(abs(y), w, 0); if y<0 then @.i= '-'@.i
end /*i*/ /* [↑] negative case.*/
 
do while #\==0; ctr.= 0; L= 'ffff'x; low= !.#._b; n= !.#._n; $= !.#._i; H=
#= #-1 /* [↑] is the radix. */
do j=low for n; parse var @.j =($) _ +1; ctr._= ctr._ + 1
if ctr._==1 & _\=='' then do; if _<<L then L=_; if _>>H then H=_
end /* ↑↑ */
end /*j*/ /* └┴─────◄─── << is a strict comparison.*/
_= /* ┌──◄─── >> " " " " */
if L>>H then iterate /*◄─────┘ */
if L==H & ctr._==0 then do; #= #+1; !.#._b= low; !.#._n= n; !.#._i= $+1; iterate
end
L= c2d(L); H= c2d(H); ?= ctr._ + low; top._= ?; ts= mote
max= L
do k=L to H; _= d2c(k, 1); c= ctr._ /* [↓] swap 2 item radices.*/
if c>ts then parse value c k with ts max; ?= ?+c; top._= ?
end /*k*/
piv= low /*set PIVot to the low part of the sort*/
do while piv<low+n
it= @.piv
do forever; parse var it =($) _ +1; c= top._ -1
if piv>=c then leave; top._= c; ?= @.c; @.c= it; it= ?
end /*forever*/
top._= piv; @.piv= it; piv= piv + ctr._
end /*while piv<low+n */
i= max
do until i==max; _= d2c(i, 1); i= i+1; if i>H then i= L; d= ctr._
if d<=mote then do; if d<2 then iterate; b= top._
do k=b+1 for d-1; q= @.k
do j=k-1 by -1 to b while q<<@.j; jp= j+1; @.jp= @.j
end /*j*/
jp= j+1; @.jp= q
end /*k*/
iterate
end
#= #+1; !.#._b= top._; !.#._n= d; !.#._i= $ + 1
end /*until i==max*/
end /*while #\==0 */
#= 0 /* [↓↓↓] handle neg. and pos. arrays. */
do i=size by -1 for size; if @.i>=0 then iterate; #= #+1; @@.#= @.i
end /*i*/
do j=1 for size; if @.j>=0 then do; #= #+1; @@.#= @.j; end; @.j= @@.j+0
end /*j*/ /* [↑↑↑] combine 2 lists into 1 list. */
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
selection: procedure expose @.; parse arg n
do j=1 for n-1; _= @.j; p= j
do k=j+1 to n; if @.k>=_ then iterate
_= @.k; p= k /*this item is out─of─order, swap later*/
end /*k*/
if p==j then iterate /*if the same, the order of items is OK*/
_= @.j; @.j= @.p; @.p= /*swap 2 items that're out─of─sequence.*/
end /*j*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
shell: procedure expose @.; parse arg N /*obtain the N from the argument list*/
i= N % 2 /*% is integer division in REXX. */
do while i\==0
do j=i+1 to N; k= j; p= k-i /*P: previous item*/
_= @.j
do while k>=i+1 & @.p>_; @.k= @.p; k= k-i; p= k-i
end /*while k≥i+1*/
@.k= _
end /*j*/
if i==2 then i= 1
else i= i * 5 % 11
end /*while i¬==0*/; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
 
(Shown at &nbsp; '''<sup>7</sup>/<sub>8</sub>''' &nbsp; size.)
<pre style="font-size:88%">
│ 250 numbers │ 500 numbers │ 1,000 numbers │ 2,000 numbers │ 4,000 numbers │
sort type │ allONES ascend random │ allONES ascend random │ allONES ascend random │ allONES ascend random │ allONES ascend random │
────────────┼─────────────────────────┼─────────────────────────┼─────────────────────────┼─────────────────────────┼─────────────────────────┤
bubble │ 0.00 0.00 0.06 │ 0.00 0.00 0.28 │ 0.00 0.00 1.11 │ 0.00 0.02 4.39 │ 0.00 0.00 17.53 │
cocktail │ 0.00 0.00 0.08 │ 0.00 0.02 0.27 │ 0.00 0.02 1.13 │ 0.00 0.00 4.75 │ 0.00 0.00 18.19 │
cocktailSB │ 0.00 0.00 0.05 │ 0.02 0.00 0.22 │ 0.00 0.00 0.91 │ 0.02 0.00 3.59 │ 0.02 0.02 14.16 │
comb │ 0.02 0.00 0.02 │ 0.00 0.00 0.02 │ 0.03 0.03 0.03 │ 0.06 0.06 0.08 │ 0.14 0.14 0.20 │
exchange │ 0.00 0.00 0.00 │ 0.02 0.02 0.02 │ 0.02 0.00 0.05 │ 0.03 0.02 0.08 │ 0.06 0.05 0.20 │
gnome │ 0.00 0.06 0.06 │ 0.00 0.11 0.24 │ 0.00 0.16 0.86 │ 0.00 3.50 3.61 │ 0.02 8.95 14.08 │
heap │ 0.00 0.00 0.00 │ 0.02 0.02 0.02 │ 0.03 0.06 0.05 │ 0.05 0.11 0.11 │ 0.08 0.25 0.25 │
insertion │ 0.00 0.00 0.03 │ 0.00 0.02 0.13 │ 0.00 0.00 0.47 │ 0.02 0.02 1.88 │ 0.02 0.02 7.84 │
merge │ 0.02 0.02 0.02 │ 0.00 0.00 0.02 │ 0.03 0.03 0.03 │ 0.05 0.05 0.08 │ 0.11 0.13 0.17 │
pancake │ 0.00 0.00 0.08 │ 0.02 0.00 0.30 │ 0.00 0.00 1.20 │ 0.02 0.02 4.73 │ 0.02 0.00 19.63 │
quick │ 0.00 0.00 0.00 │ 0.00 0.00 0.00 │ 0.00 0.00 0.02 │ 0.00 0.00 0.05 │ 0.00 0.00 0.09 │
radix │ 0.00 0.00 0.00 │ 0.00 0.03 0.03 │ 0.02 0.03 0.05 │ 0.05 0.08 0.08 │ 0.09 0.14 0.14 │
selection │ 0.02 0.03 0.03 │ 0.09 0.08 0.08 │ 0.33 0.33 0.38 │ 1.22 1.39 1.55 │ 4.95 4.86 5.30 │
shell │ 0.02 0.00 0.00 │ 0.00 0.00 0.02 │ 0.02 0.02 0.05 │ 0.05 0.05 0.09 │ 0.13 0.11 0.22 │
────────────┴─────────────────────────┴─────────────────────────┴─────────────────────────┴─────────────────────────┴─────────────────────────┘
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class Array
def radix_sort(base=10) # negative value is inapplicable.
ary = dup
Line 2,272 ⟶ 3,641:
puts
end
end</langsyntaxhighlight>
Array#sort is a built-in method.
 
Line 2,310 ⟶ 3,679:
insertion_sort 0.053 5.298 --.--- --.---
bubble_sort 0.206 17.232 --.--- --.---
</pre>
 
=={{header|Sidef}}==
{{trans|Ruby}}
 
''Array#sort'' is a built-in method.
 
<syntaxhighlight lang="ruby">class Array {
method radix_sort(base=10) {
var rounds = ([self.minmax].map{.abs}.max.ilog(base) + 1)
for i in (0..rounds) {
var buckets = (2*base -> of {[]})
var base_i = base**i
for n in self {
var digit = idiv(n, base_i)%base
digit += base if (0 <= n)
buckets[digit].append(n)
}
self = buckets.flat
}
return self
}
 
func merge(left, right) {
var result = []
while (left && right) {
result << [right,left].min_by{.first}.shift
}
result + left + right
}
 
method merge_sort {
var len = self.len
len < 2 && return self
 
var (left, right) = self.part(len>>1)
 
left = left.merge_sort
right = right.merge_sort
 
merge(left, right)
}
 
method quick_sort {
self.len < 2 && return self
var p = self.rand # to avoid the worst cases
var g = self.group_by {|x| x <=> p }
(g{-1} \\ []).quick_sort + (g{0} \\ []) + (g{1} \\ []).quick_sort
}
 
method shell_sort {
var h = self.len
while (h >>= 1) {
range(h, self.end).each { |i|
var k = self[i]
var j
for (j = i; (j >= h) && (k < self[j - h]); j -= h) {
self[j] = self[j - h]
}
self[j] = k
}
}
return self
}
 
method insertion_sort {
{ |i|
var j = i
var k = self[i+1]
while ((j >= 0) && (k < self[j])) {
self[j+1] = self[j]
j--
}
self[j+1] = k
} * self.end
return self
}
 
method bubble_sort {
loop {
var swapped = false
{ |i|
if (self[i] > self[i+1]) {
self[i, i+1] = self[i+1, i]
swapped = true
}
} << ^self.end
swapped || break
}
return self
}
}
 
var data_size = [1e2, 1e3, 1e4, 1e5]
var data = []
data_size.each {|size|
var ary = @(1..size)
data << [size.of(1), ary, ary.shuffle, ary.reverse]
}
 
data = data.transpose
 
var data_type = ["set to all ones", "ascending sequence",
"randomly shuffled", "descending sequence"]
print("Array size: ")
say data_size.map{|size| "%9d" % size}.join
 
data.each_kv {|i, arys|
say "\nData #{data_type[i]}:"
[:sort, :radix_sort, :quick_sort, :merge_sort,
:shell_sort, :insertion_sort, :bubble_sort].each {|m|
printf("%20s ", m)
var timeout = false
arys.each {|ary|
if (!timeout) {
var t0 = Time.micro
ary.clone.(m)
printf(" %7.3f", (var t1 = (Time.micro - t0)))
timeout = true if (t1 > 1.5)
}
else {
print(" --.---")
}
}
say ''
}
}</syntaxhighlight>
{{out}}
<pre>
Array size: 100 1000 10000 100000
 
Data set to all ones:
sort 0.000 0.001 0.011 0.104
radix_sort 0.003 0.026 0.249 2.957
quick_sort 0.004 0.003 0.029 0.298
merge_sort 0.009 0.112 1.269 17.426
shell_sort 0.006 0.164 2.092 --.---
insertion_sort 0.002 0.016 0.149 1.261
bubble_sort 0.001 0.007 0.064 0.647
 
Data ascending sequence:
sort 0.000 0.001 0.011 0.109
radix_sort 0.006 0.063 0.739 9.657
quick_sort 0.006 0.080 0.865 9.578
merge_sort 0.008 0.102 1.178 14.079
shell_sort 0.006 0.091 1.441 16.398
insertion_sort 0.001 0.012 0.124 1.258
bubble_sort 0.001 0.006 0.063 0.628
 
Data randomly shuffled:
sort 0.001 0.009 0.126 1.632
radix_sort 0.006 0.060 0.731 8.768
quick_sort 0.005 0.058 0.742 9.516
merge_sort 0.010 0.132 1.639 --.---
shell_sort 0.010 0.167 2.931 --.---
insertion_sort 0.019 1.989 --.--- --.---
bubble_sort 0.069 7.333 --.--- --.---
 
Data descending sequence:
sort 0.000 0.001 0.012 0.129
radix_sort 0.006 0.061 0.732 8.926
quick_sort 0.005 0.061 0.720 8.712
merge_sort 0.008 0.097 1.148 13.456
shell_sort 0.008 0.133 1.910 --.---
insertion_sort 0.040 3.884 --.--- --.---
bubble_sort 0.092 8.819 --.--- --.---
</pre>
 
Line 2,324 ⟶ 3,859:
{{libheader|Tk}}
{{tcllib|struct::list}}
<langsyntaxhighlight lang="tcl">###############################################################################
# measure and plot times
package require Tk
Line 2,545 ⟶ 4,080:
create_log10_plot "Sorting a '$type' list" size time $sizes $times $algorithms $shapes $colours
}
puts "\ntimes in microseconds, average of $runs runs"</langsyntaxhighlight>
 
{{omit from|GUISS}}
Line 2,580 ⟶ 4,115:
[[Image:Tcl_sort_reversed.png]]
[[Image:Tcl_sort_random.png]]
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-sort}}
{{libheader|Wren-fmt}}
The quick, insertion and shell sorts all use the 'in place' implementations in the Wren-sort module.
 
The radix sort is lifted from the task of that name and, although more complicated, appears to be much faster than the Kotlin version.
 
For the bubble sort, I have used the optimized Kotlin implementation.
 
I've limited the size of the arrays to 50,000 though even then the program takes the best part of half an hour to run, due to the extreme slowness of the bubble and insertion sorts for large amounts of shuffled data.
 
Results presented in tabular form as Wren doesn't have a plotting library available at the present time.
<syntaxhighlight lang="wren">import "random" for Random
import "./sort" for Sort
import "./fmt" for Fmt
 
var rand = Random.new()
 
var onesSeq = Fn.new { |n| List.filled(n, 1) }
 
var shuffledSeq = Fn.new { |n|
var seq = List.filled(n, 0)
for (i in 0...n) seq[i] = 1 + rand.int(10 * n)
return seq
}
 
var ascendingSeq = Fn.new { |n|
var seq = shuffledSeq.call(n)
seq.sort()
return seq
}
 
var bubbleSort = Fn.new { |a|
var n = a.count
while (true) {
var n2 = 0
for (i in 1...n) {
if (a[i - 1] > a[i]) {
a.swap(i, i - 1)
n2 = i
}
}
n = n2
if (n == 0) break
}
}
 
// counting sort of 'a' according to the digit represented by 'exp'
var countSort = Fn.new { |a, exp|
var n = a.count
var output = [0] * n
var count = [0] * 10
for (i in 0...n) {
var t = (a[i]/exp).truncate % 10
count[t] = count[t] + 1
}
for (i in 1..9) count[i] = count[i] + count[i-1]
for (i in n-1..0) {
var t = (a[i]/exp).truncate % 10
output[count[t] - 1] = a[i]
count[t] = count[t] - 1
}
for (i in 0...n) a[i] = output[i]
}
 
// sorts 'a' in place
var radixSort = Fn.new { |a|
// check for negative elements
var min = a.reduce { |m, i| (i < m) ? i : m }
// if there are any, increase all elements by -min
if (min < 0) (0...a.count).each { |i| a[i] = a[i] - min }
// now get the maximum to know number of digits
var max = a.reduce { |m, i| (i > m) ? i : m }
// do counting sort for each digit
var exp = 1
while ((max/exp).truncate > 0) {
countSort.call(a, exp)
exp = exp * 10
}
// if there were negative elements, reduce all elements by -min
if (min < 0) (0...a.count).each { |i| a[i] = a[i] + min }
}
 
var measureTime = Fn.new { |sort, seq|
var start = System.clock
sort.call(seq)
return ((System.clock - start) * 1e6).round // microseconds
}
 
var runs = 10
var lengths = [1, 10, 100, 1000, 10000, 50000]
var sorts = [
bubbleSort,
Fn.new { |a| Sort.insertion(a) },
Fn.new { |a| Sort.quick(a) },
radixSort,
Fn.new { |a| Sort.shell(a) }
]
 
var sortTitles = ["Bubble", "Insert", "Quick ", "Radix ", "Shell "]
var seqTitles = ["All Ones", "Ascending", "Shuffled"]
var totals = List.filled(seqTitles.count, null)
for (i in 0...totals.count) {
totals[i] = List.filled(sorts.count, null)
for (j in 0...sorts.count) totals[i][j] = List.filled(lengths.count, 0)
}
var k = 0
for (n in lengths) {
var seqs = [onesSeq.call(n), ascendingSeq.call(n), shuffledSeq.call(n)]
for (r in 0...runs) {
for (i in 0...seqs.count) {
for (j in 0...sorts.count) {
var seq = seqs[i].toList
totals[i][j][k] = totals[i][j][k] + measureTime.call(sorts[j], seq)
}
}
}
k = k + 1
}
System.print("All timings in microseconds\n")
System.write("Sequence length")
for (len in lengths) Fmt.write("$8d ", len)
System.print("\n")
for (i in 0...seqTitles.count) {
System.print(" %(seqTitles[i]):")
for (j in 0...sorts.count) {
System.write(" %(sortTitles[j]) ")
for (k in 0...lengths.count) {
var time = (totals[i][j][k] / runs).round
Fmt.write("$8d ", time)
}
System.print()
}
System.print("\n")
}</syntaxhighlight>
 
{{out}}
<pre>
All timings in microseconds
 
Sequence length 1 10 100 1000 10000 50000
 
All Ones:
Bubble 1 2 9 61 643 3225
Insert 1 3 16 118 1256 6338
Quick 1 8 92 983 14746 87660
Radix 6 13 62 460 4823 24379
Shell 1 5 59 770 9542 48873
 
 
Ascending:
Bubble 1 2 8 61 637 3221
Insert 1 3 16 118 1251 6371
Quick 1 7 65 643 9149 54199
Radix 7 23 169 1648 21428 130609
Shell 1 5 60 779 9537 49041
 
 
Shuffled:
Bubble 1 7 451 37271 4025966 99834073
Insert 0 7 295 24040 2597162 64875212
Quick 1 8 101 1149 16256 95590
Radix 5 24 163 1688 22443 136228
Shell 1 8 111 1514 25180 230897
</pre>
 
The results are much the same as one might have expected beforehand.
 
As far as the shuffled data is concerned, quick sort is the fastest though radix and shell sorts are also reasonable performers. Bubble and insertion sorts are very slow indeed for large amounts of data.
 
Conversely, if the data is already sorted into ascending order, bubble and insertion sorts are much faster than the others and radix sort is the slowest.
 
If all data is the same, a similar pattern emerges except that radix sort performs better than both shell and quick sorts, the latter being the slowest.
2,747

edits