Navigation Menu

Skip to content

Commit

Permalink
Changes the threshold in Array#sort for determining whether to use in…
Browse files Browse the repository at this point in the history
…sertion sort or quicksort. The threshold was 6, but it is now 13. Results and methodology below.

## Code

def quicksort(v, tally=[])
  return v if v.nil? or v.length <= 1
  less, more = v[1..-1].partition { |i| tally << 1; i < v[0] }
  quicksort(less, tally) + [v[0]] + quicksort(more, tally)
end

def qsort(v)
  array = []
  quicksort(v, array)
  array.size
end

def isort(list)
  tally = 0
  for i in 1..(list.length - 1)
    value = list[i]
    j = i - 1
    while j >= 0 and list[j] > value
      list[j + 1] = list[j]
      j -= 1
      tally += 1
    end
    list[j + 1] = value
  end
  tally
end

def random_array(size)
  array = []
  size.times { array << rand(1_000_000) }
  array
end

class Array
  def average
    sum / size
  end

  def sum
    inject(0) {|s, v| s + v }
  end
end

#################################
q_results = Array.new(51) { [] }
i_results = Array.new(51) { [] }

10_000.times do
  (1..50).map do |i|
    q_results[i] << qsort(random_array(i))
    i_results[i] << isort(random_array(i))
  end
end

puts "Size\t| Quicksort\t| Insertio[i].average}\t| #{i_results[i].average}"
end

## Results
Size    | Quicksort     | Insertion sort
1       | 0     | 0
2       | 1     | 0
3       | 2     | 1
4       | 4     | 2
5       | 7     | 5
6       | 10    | 7
7       | 13    | 10
8       | 16    | 14
9       | 20    | 17
10      | 24    | 22
11      | 28    | 27
12      | 32    | 32
13      | 37    | 38
14      | 41    | 45
15      | 46    | 52
16      | 51    | 59
17      | 55    | 68
18      | 60    | 76
19      | 65    | 85
20      | 71    | 94
21      | 76    | 104
22      | 81    | 115
23      | 87    | 126
24      | 92    | 138
25      | 98    | 150
26      | 104   | 162
27      | 110   | 175
28      | 115   | 188
29      | 121   | 203
30      | 127   | 217
31      | 134   | 232
32      | 139   | 247
33      | 145   | 264
34      | 152   | 280
35      | 158   | 297
36      | 164   | 314
37      | 171   | 333
38      | 177   | 351
39      | 184   | 370
40      | 191   | 390
41      | 197   | 410
42
43      | 211   | 452
44      | 216   | 472
45      | 224   | 494
46      | 231   | 517
47      | 238   | 541
48      | 244   | 563
49      | 251   | 588
50      | 258   | 612

real    1m57.527s
user    1m56.007s
sys     0m0.314s

## uname -a
Darwin baits-190183.reshall.umich.edu 10.6.0 Darwin Kernel Version 10.6.0: Wed Nov 10 18:13:17 PST 2010; root:xnu-1504.9.26~3/RELEASE_I386 i386 i386
  • Loading branch information
seydar committed Feb 12, 2011
1 parent c4bcccb commit 28da87d
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion kernel/common/array.rb
Expand Up @@ -1538,12 +1538,20 @@ def sort(&block)
end

# Sorts this Array in-place. See #sort.
#
# The threshold for choosing between Insertion sort and Quicksort
# is 10, as determined by a bit of quick tests.
# Solving directly for recurrence relations is impossible, since quicksort
# depends on the partition sizes, which is dependent upon the arrangement
# of the array.
#
# For results and methodology, see the commit message.
def sort_inplace(&block)
Ruby.check_frozen

return self unless @total > 1

if (@total - @start) < 6
if (@total - @start) < 13
if block
isort_block! @start, (@start + @total) - 1, block
else
Expand Down

0 comments on commit 28da87d

Please sign in to comment.