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

     
    weird_sort(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
    Weird sort

    Fastest: N/A

    Slowest: N/A

Latest run results:
Run details: (Test run date: 2 years ago)
Mozilla/5.0 (Android 10; Mobile; rv:109.0) Gecko/112.0 Firefox/112.0
Firefox Mobile 112 on Android
View result in a separate tab
Test name Executions per second
Built-in Sort 10399.7 Ops/sec
Naive Quicksort 1437.9 Ops/sec
Inplace Quicksort 4625.6 Ops/sec
Heap Sort 1587.5 Ops/sec
Merge Sort 1458.4 Ops/sec
Shell Sort 4666.2 Ops/sec
Comb Sort 1801.2 Ops/sec
Insertion Sort 536.2 Ops/sec
Fast QuickSort 5242.5 Ops/sec
mSort 1909.5 Ops/sec
Radix Bucket Sort 820.9 Ops/sec
Bubble Sort 171.7 Ops/sec
Weird sort 21.7 Ops/sec