HTML Preparation code:
x
 
1
<script>
2
  function swap(ary, a, b) {
3
      [ary[b], ary[a]] = [ary[a], ary[b]];
4
  }
5
  
6
  // Built-in with comparison function (default sorting is "dictionary-style")
7
  function builtin_sort(ary) {
8
      return ary.sort(function(a, b) {
9
          return a - b;
10
      });
11
  }
12
  
13
  // Bubble Sort
14
  function bubble_sort(ary) {
15
      var a, b;
16
      for (a = 0; a < ary.length; a++) {
17
          for (b = a + 1; b < ary.length; b++) {
18
              if (ary[a] > ary[b]) {
19
                  swap(ary, a, b);
20
              }
21
          }
22
      }
23
  
24
      return ary;
25
  }
26
  //Insertion sort
27
  function insertion_sort(ary) {
28
        for(var i=1,l=ary.length;i<l;i++) {
29
            var value = ary[i];
30
            for(var j=i - 1;j>=0;j--) {
31
                if(ary[j] <= value)
32
                    break;
33
                ary[j+1] = ary[j];
34
            }
35
            ary[j+1] = value;
36
        }
37
        return ary;
38
  }
39
  
40
  // Naive (but understandable) quicksort (memory hog)
41
  function naive_quicksort(ary) {
42
      if (ary.length <= 1) {
43
          return ary;
44
      }
45
  
46
      var less = [],
47
          greater = [],
48
          pivot = ary.pop();
49
  
50
      for (var i = 0; i < ary.length; i++) {
51
          if (ary[i] < pivot) {
52
              less.push(ary[i]);
53
          } else {
54
              greater.push(ary[i]);
55
          }
56
      }
57
  
58
      less = naive_quicksort(less);
59
      greater = naive_quicksort(greater);
60
  
61
      return less.concat(pivot, greater);
62
  }
63
  
64
  // In place quicksort
65
  function inplace_quicksort_partition(ary, start, end, pivotIndex) {
66
      var i = start, j = end;
67
      var pivot = ary[pivotIndex];
68
      
69
      while(true) {
70
          while(ary[i] < pivot) {i++};
71
          j--;
72
          while(pivot < ary[j]) {j--};
73
          if(!(i<j)) {
74
              return i;
75
          }
76
          swap(ary,i,j);
77
          i++;
78
     }
79
  }
80
  
81
  function inplace_quicksort(ary, start, end) {
82
      if (start < end - 1) {
83
          var pivotIndex = Math.round((start + end) / 2);
84
  
85
          pivotIndex = inplace_quicksort_partition(ary, start, end, pivotIndex);
86
  
87
          inplace_quicksort(ary, start, pivotIndex - 1);
88
          inplace_quicksort(ary, pivotIndex + 1, end);
89
      }
90
  
91
      return ary;
92
  }
93
  
94
  // Heap sort
95
  function heapSort(ary) {
96
      heapify(ary);
97
  
98
      for (var end = ary.length - 1; end > 0; end--) {
99
          swap(ary, end, 0);
100
          shiftDown(ary, 0, end - 1);
101
      }
102
  
103
      return ary;
104
  }
105
  
106
  function heapify(ary) {
107
      for (var start = (ary.length >> 1) - 1; start >= 0; start--) {
108
          shiftDown(ary, start, ary.length - 1);
109
      }
110
  }
111
  
112
  function shiftDown(ary, start, end) {
113
      var root = start,
114
          child, s;
115
  
116
      while (root * 2 + 1 <= end) {
117
          child = root * 2 + 1;
118
          s = root;
119
  
120
          if (ary[s] < ary[child]) {
121
              s = child;
122
          }
123
  
124
          if (child + 1 <= end && ary[s] < ary[child + 1]) {
125
              s = child + 1;
126
          }
127
  
128
          if (s !== root) {
129
              swap(ary, root, s);
130
              root = s;
131
          } else {
132
              return;
133
          }
134
      }
135
  }
136
  
137
  // Merge sort
138
  function merge_sort(ary) {
139
      if (ary.length <= 1) {
140
          return ary;
141
      }
142
  
143
      var m = ary.length >> 1;
144
  
145
      var left = ary.slice(0, m),
146
          right = ary.slice(m);
147
  
148
      return merge(merge_sort(left), merge_sort(right));
149
  }
150
  
151
  function merge(left, right) {
152
      var result = [],
153
          li = 0, ri = 0;
154
  
155
      while (li < left.length || ri < right.length) {
156
          if (li < left.length && ri < right.length) {
157
              if (left[li] <= right[ri]) {
158
                  result.push(left[li]);
159
                  li++;
160
              } else {
161
                  result.push(right[ri]);
162
                  ri++;
163
              }
164
          } else if (li < left.length) {
165
              result.push(left[li]);
166
              li++;
167
          } else if (ri < right.length) {
168
              result.push(right[ri]);
169
              ri++;
170
          }
171
      }
172
  
173
      return result;
174
  }
175
  
176
  // Shell sort
177
  function shell_sort(ary) {
178
      var inc = Math.round(ary.length / 2),
179
          i, j, t;
180
  
181
      while (inc > 0) {
182
          for (i = inc; i < ary.length; i++) {
183
              t = ary[i];
184
              j = i;
185
              while (j >= inc && ary[j - inc] > t) {
186
                  ary[j] = ary[j - inc];
187
                  j -= inc;
188
              }
189
              ary[j] = t;
190
          }
191
          inc = Math.round(inc / 2.2);
192
      }
193
  
194
      return ary;
195
  }
196
  //Comb Sort (Basically bubblesort with a small modification, but heaps faster)
197
function comb_sort(ary) {
198
    var gap = ary.length;
199
    while(true) {
200
        gap = newgap(gap);
201
        var swapped = false;
202
        for(var i=0,l=ary.length;i<l;i++) {
203
            var j = i + gap;
204
            if(ary[i] < ary[j]) {
205
                swap(ary,i,j);
206
                swapped = true;
207
            }
208
        }
209
        if(gap == 1 && !swapped)
210
             break;
211
    }
212
    return ary;   
213
}
214
function newgap(gap) {
215
    gap = ((gap * 10) / 13) | 0;
216
    if(gap == 9 || gap == 10)
217
        gap = 11;
218
    if(gap < 1)
219
         gap = 1;
220
    return gap;
221
}
222
//faster quicksort using a stack to eliminate recursion, sorting inplace to reduce memory usage, and using insertion sort for small partition sizes
223
function fast_quicksort(ary) {
224
    var stack = [];
225
    var entry = [0,ary.length,2 * Math.floor(Math.log(ary.length)/Math.log(2))];
226
    stack.push(entry);
227
    while(stack.length > 0) {
228
        entry = stack.pop();
229
        var start = entry[0];
230
        var end = entry[1];
231
        var depth = entry[2];
232
        if(depth == 0) {
233
         ary = shell_sort_bound(ary,start,end);
234
         continue;
235
        }
236
        depth--;
237
        var pivot = Math.round((start + end) / 2);
238
            
239
        var pivotNewIndex = inplace_quicksort_partition(ary,start,end, pivot);
240
        if(end - pivotNewIndex > 16) {
241
            entry = [pivotNewIndex,end,depth];
242
            stack.push(entry);
243
        }
244
        if(pivotNewIndex - start > 16) {
245
            entry = [start,pivotNewIndex,depth];
246
            stack.push(entry);
247
        }
248
    }
249
    ary = insertion_sort(ary);
250
    return ary;
251
}
252
function shell_sort_bound(ary,start,end) {
253
      var inc = Math.round((start + end)/2),
254
          i, j, t;
255
  
256
      while (inc >= start) {
257
          for (i = inc; i < end; i++) {
258
              t = ary[i];
259
              j = i;
260
              while (j >= inc && ary[j - inc] > t) {
261
                  ary[j] = ary[j - inc];
262
                  j -= inc;
263
              }
264
              ary[j] = t;
265
          }
266
          inc = Math.round(inc / 2.2);
267
      }
268
  
269
      return ary;
270
  }
271
272
function mSort(list) {
273
                if (list.length < 14) {
274
                    return insertion_sort(list);
275
                }
276
                
277
                var half = Math.floor(list.length / 2);
278
                var a = mSort(list.slice(0, half));
279
                var b = mSort(list.slice(half, list.length));
280
                var aCount = 0;
281
                var bCount = 0;
282
                var returnList = [];
283
                
284
                while (true) {
285
                    if (a[aCount] <= b[bCount]) {
286
                        returnList.push(a[aCount]);
287
                        aCount++;
288
                        if (aCount === a.length) {
289
                            returnList = returnList.concat(b.slice(bCount, b.length));
290
                            break;
291
                        }
292
                    }
293
                    else {
294
                        returnList.push(b[bCount]);
295
                        bCount++;
296
                        if (bCount === b.length) {
297
                            returnList = returnList.concat(a.slice(aCount, a.length));
298
                            break;
299
                        }
300
                    }
301
                }
302
                return returnList;
303
            }
304
  
305
  function bubbleSort(items) {
306
  var length = items.length;
307
  for (var i = 0; i < length; i++) { //Number of passes
308
    for (var j = 0; j < (length - i - 1); j++) { //Notice that j < (length - i)
309
      //Compare the adjacent positions
310
      if(items[j] > items[j+1]) {
311
        //Swap the numbers
312
        var tmp = items[j];  //Temporary variable to hold the current number
313
        items[j] = items[j+1]; //Replace current number with adjacent number
314
        items[j+1] = tmp; //Replace adjacent number with current number
315
      }
316
    }        
317
  }
318
}
319
  
320
  https://stackoverflow.com/a/38979903/8769328
321
  function radixBucketSort (arr) {
322
    var idx1, idx2, idx3, len1, len2, radix, radixKey;
323
    var radices = {}, buckets = {}, num, curr;
324
    var currLen, radixStr, currBucket;
325
326
    len1 = arr.length;
327
    len2 = 10;  // radix sort uses ten buckets
328
329
    // find the relevant radices to process for efficiency        
330
    for (idx1 = 0;idx1 < len1;idx1++) {
331
      radices[arr[idx1].toString().length] = 0;
332
    }
333
334
    // loop for each radix. For each radix we put all the items
335
    // in buckets, and then pull them out of the buckets.
336
    for (radix in radices) {          
337
      // put each array item in a bucket based on its radix value
338
      len1 = arr.length;
339
      for (idx1 = 0;idx1 < len1;idx1++) {
340
        curr = arr[idx1];
341
        // item length is used to find its current radix value
342
        currLen = curr.toString().length;
343
        // only put the item in a radix bucket if the item
344
        // key is as long as the radix
345
        if (currLen >= radix) {
346
          // radix starts from beginning of key, so need to
347
          // adjust to get redix values from start of stringified key
348
          radixKey = curr.toString()[currLen - radix];
349
          // create the bucket if it does not already exist
350
          if (!buckets.hasOwnProperty(radixKey)) {
351
            buckets[radixKey] = [];
352
          }
353
          // put the array value in the bucket
354
          buckets[radixKey].push(curr);          
355
        } else {
356
          if (!buckets.hasOwnProperty('0')) {
357
            buckets['0'] = [];
358
          }
359
          buckets['0'].push(curr);          
360
        }
361
      }
362
      // for current radix, items are in buckets, now put them
363
      // back in the array based on their buckets
364
      // this index moves us through the array as we insert items
365
      idx1 = 0;
366
      // go through all the buckets
367
      for (idx2 = 0;idx2 < len2;idx2++) {
368
        // only process buckets with items
369
        if (buckets[idx2] != null) {
370
          currBucket = buckets[idx2];
371
          // insert all bucket items into array
372
          len1 = currBucket.length;
373
          for (idx3 = 0;idx3 < len1;idx3++) {
374
            arr[idx1++] = currBucket[idx3];
375
          }
376
        }
377
      }
378
      buckets = {};
379
    }
380
  }
381
</script>
Script Preparation code:
 
var input = [];
for (var i = 0; i < 1000; i++) {
  input[i] = Math.round(Math.random() * 1000000);
}
Tests:
  • Built-in Sort

     
    builtin_sort(input.slice(0));
  • Naive Quicksort

     
    naive_quicksort(input.slice(0));
  • Inplace Quicksort

     
    inplace_quicksort(input.slice(0), 0, input.length);
  • Heap Sort

     
    heapSort(input.slice(0));
  • Merge Sort

     
    merge_sort(input.slice(0));
  • Shell Sort

     
    shell_sort(input.slice(0));
  • Comb Sort

     
    comb_sort(input.slice(0));
  • Insertion Sort

     
    insertion_sort(input.slice(0));
  • Fast QuickSort

     
    fast_quicksort(input.slice(0));
  • mSort

     
    mSort(input.slice(0));
  • Radix Bucket Sort

     
    radixBucketSort(input.slice(0)) 
  • Bubble Sort

     
    bubbleSort(input.slice(0));
Rendered benchmark preparation results:

Suite status: <idle, ready to run>

Previous results

Experimental features:

  • Test case name Result
    Built-in Sort
    Naive Quicksort
    Inplace Quicksort
    Heap Sort
    Merge Sort
    Shell Sort
    Comb Sort
    Insertion Sort
    Fast QuickSort
    mSort
    Radix Bucket Sort
    Bubble Sort

    Fastest: N/A

    Slowest: N/A

Latest run results:
Run details: (Test run date: 3 years ago)
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
IE 11 on Windows
View result in a separate tab
Test name Executions per second
Built-in Sort 5309.9 Ops/sec
Naive Quicksort 937.0 Ops/sec
Inplace Quicksort 0.0 Ops/sec
Heap Sort 0.0 Ops/sec
Merge Sort 822.5 Ops/sec
Shell Sort 8340.3 Ops/sec
Comb Sort 0.0 Ops/sec
Insertion Sort 1122.7 Ops/sec
Fast QuickSort 0.0 Ops/sec
mSort 2235.3 Ops/sec
Radix Bucket Sort 437.9 Ops/sec
Bubble Sort 426.0 Ops/sec