Compare sorting algorithms' performance
Array#sort is a built-in method.
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 ''
}
}
Output:
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 --.--- --.---
Last updated