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

     
    countingSort(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
    Counting 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; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36
Chrome 99 on Windows
View result in a separate tab
Test name Executions per second
Built-in Sort 1325094.9 Ops/sec
Naive Quicksort 458700.7 Ops/sec
Inplace Quicksort 2363510.2 Ops/sec
Heap Sort 3020869.5 Ops/sec
Merge Sort 832407.2 Ops/sec
Shell Sort 2869929.8 Ops/sec
Comb Sort 2443370.5 Ops/sec
Insertion Sort 3521655.2 Ops/sec
Fast QuickSort 2866964.2 Ops/sec
mSort 3317536.8 Ops/sec
Radix Bucket Sort 612489.4 Ops/sec
Bubble Sort 3091910.5 Ops/sec
Counting Sort 645541.7 Ops/sec