Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Javascript Sorting Algorithms large
(version: 0)
Port from jsperf(https://jsperf.com/sorting-algorithms/58)
Comparing performance of:
Built-in Sort vs Fast QuickSort vs Radix Bucket Sort
Created:
4 years ago
by:
Registered User
Jump to the latest result
HTML Preparation code:
<script> function swap(ary, a, b) { var t = ary[a]; ary[a] = ary[b]; ary[b] = t; } // Built-in with comparison function (default sorting is "dictionary-style") function builtin_sort(ary) { return ary.sort(function(a, b) { return a - b; }); } // Bubble Sort function bubble_sort(ary) { var a, b; for (a = 0; a < ary.length; a++) { for (b = a + 1; b < ary.length; b++) { if (ary[a] > ary[b]) { swap(ary, a, b); } } } return ary; } //Insertion sort function insertion_sort(ary) { for(var i=1,l=ary.length;i<l;i++) { var value = ary[i]; for(var j=i - 1;j>=0;j--) { if(ary[j] <= value) break; ary[j+1] = ary[j]; } ary[j+1] = value; } return ary; } // Naive (but understandable) quicksort (memory hog) function naive_quicksort(ary) { if (ary.length <= 1) { return ary; } var less = [], greater = [], pivot = ary.pop(); for (var i = 0; i < ary.length; i++) { if (ary[i] < pivot) { less.push(ary[i]); } else { greater.push(ary[i]); } } less = naive_quicksort(less); greater = naive_quicksort(greater); return less.concat(pivot, greater); } // In place quicksort function inplace_quicksort_partition(ary, start, end, pivotIndex) { var i = start, j = end; var pivot = ary[pivotIndex]; while(true) { while(ary[i] < pivot) {i++}; j--; while(pivot < ary[j]) {j--}; if(!(i<j)) { return i; } swap(ary,i,j); i++; } } function inplace_quicksort(ary, start, end) { if (start < end - 1) { var pivotIndex = Math.round((start + end) / 2); pivotIndex = inplace_quicksort_partition(ary, start, end, pivotIndex); inplace_quicksort(ary, start, pivotIndex - 1); inplace_quicksort(ary, pivotIndex + 1, end); } return ary; } // Heap sort function heapSort(ary) { heapify(ary); for (var end = ary.length - 1; end > 0; end--) { swap(ary, end, 0); shiftDown(ary, 0, end - 1); } return ary; } function heapify(ary) { for (var start = (ary.length >> 1) - 1; start >= 0; start--) { shiftDown(ary, start, ary.length - 1); } } function shiftDown(ary, start, end) { var root = start, child, s; while (root * 2 + 1 <= end) { child = root * 2 + 1; s = root; if (ary[s] < ary[child]) { s = child; } if (child + 1 <= end && ary[s] < ary[child + 1]) { s = child + 1; } if (s !== root) { swap(ary, root, s); root = s; } else { return; } } } // Merge sort function merge_sort(ary) { if (ary.length <= 1) { return ary; } var m = ary.length >> 1; var left = ary.slice(0, m), right = ary.slice(m); return merge(merge_sort(left), merge_sort(right)); } function merge(left, right) { var result = [], li = 0, ri = 0; while (li < left.length || ri < right.length) { if (li < left.length && ri < right.length) { if (left[li] <= right[ri]) { result.push(left[li]); li++; } else { result.push(right[ri]); ri++; } } else if (li < left.length) { result.push(left[li]); li++; } else if (ri < right.length) { result.push(right[ri]); ri++; } } return result; } // Shell sort function shell_sort(ary) { var inc = Math.round(ary.length / 2), i, j, t; while (inc > 0) { for (i = inc; i < ary.length; i++) { t = ary[i]; j = i; while (j >= inc && ary[j - inc] > t) { ary[j] = ary[j - inc]; j -= inc; } ary[j] = t; } inc = Math.round(inc / 2.2); } return ary; } //Comb Sort (Basically bubblesort with a small modification, but heaps faster) function comb_sort(ary) { var gap = ary.length; while(true) { gap = newgap(gap); var swapped = false; for(var i=0,l=ary.length;i<l;i++) { var j = i + gap; if(ary[i] < ary[j]) { swap(ary,i,j); swapped = true; } } if(gap == 1 && !swapped) break; } return ary; } function newgap(gap) { gap = ((gap * 10) / 13) | 0; if(gap == 9 || gap == 10) gap = 11; if(gap < 1) gap = 1; return gap; } //faster quicksort using a stack to eliminate recursion, sorting inplace to reduce memory usage, and using insertion sort for small partition sizes function fast_quicksort(ary) { var stack = []; var entry = [0,ary.length,2 * Math.floor(Math.log(ary.length)/Math.log(2))]; stack.push(entry); while(stack.length > 0) { entry = stack.pop(); var start = entry[0]; var end = entry[1]; var depth = entry[2]; if(depth == 0) { ary = shell_sort_bound(ary,start,end); continue; } depth--; var pivot = Math.round((start + end) / 2); var pivotNewIndex = inplace_quicksort_partition(ary,start,end, pivot); if(end - pivotNewIndex > 16) { entry = [pivotNewIndex,end,depth]; stack.push(entry); } if(pivotNewIndex - start > 16) { entry = [start,pivotNewIndex,depth]; stack.push(entry); } } ary = insertion_sort(ary); return ary; } function shell_sort_bound(ary,start,end) { var inc = Math.round((start + end)/2), i, j, t; while (inc >= start) { for (i = inc; i < end; i++) { t = ary[i]; j = i; while (j >= inc && ary[j - inc] > t) { ary[j] = ary[j - inc]; j -= inc; } ary[j] = t; } inc = Math.round(inc / 2.2); } return ary; } function mSort(list) { if (list.length < 14) { return insertion_sort(list); } var half = Math.floor(list.length / 2); var a = mSort(list.slice(0, half)); var b = mSort(list.slice(half, list.length)); var aCount = 0; var bCount = 0; var returnList = []; while (true) { if (a[aCount] <= b[bCount]) { returnList.push(a[aCount]); aCount++; if (aCount === a.length) { returnList = returnList.concat(b.slice(bCount, b.length)); break; } } else { returnList.push(b[bCount]); bCount++; if (bCount === b.length) { returnList = returnList.concat(a.slice(aCount, a.length)); break; } } } return returnList; } function bubbleSort(items) { var length = items.length; for (var i = 0; i < length; i++) { //Number of passes for (var j = 0; j < (length - i - 1); j++) { //Notice that j < (length - i) //Compare the adjacent positions if(items[j] > items[j+1]) { //Swap the numbers var tmp = items[j]; //Temporary variable to hold the current number items[j] = items[j+1]; //Replace current number with adjacent number items[j+1] = tmp; //Replace adjacent number with current number } } } } https://stackoverflow.com/a/38979903/8769328 function radixBucketSort (arr) { var idx1, idx2, idx3, len1, len2, radix, radixKey; var radices = {}, buckets = {}, num, curr; var currLen, radixStr, currBucket; len1 = arr.length; len2 = 10; // radix sort uses ten buckets // find the relevant radices to process for efficiency for (idx1 = 0;idx1 < len1;idx1++) { radices[arr[idx1].toString().length] = 0; } // loop for each radix. For each radix we put all the items // in buckets, and then pull them out of the buckets. for (radix in radices) { // put each array item in a bucket based on its radix value len1 = arr.length; for (idx1 = 0;idx1 < len1;idx1++) { curr = arr[idx1]; // item length is used to find its current radix value currLen = curr.toString().length; // only put the item in a radix bucket if the item // key is as long as the radix if (currLen >= radix) { // radix starts from beginning of key, so need to // adjust to get redix values from start of stringified key radixKey = curr.toString()[currLen - radix]; // create the bucket if it does not already exist if (!buckets.hasOwnProperty(radixKey)) { buckets[radixKey] = []; } // put the array value in the bucket buckets[radixKey].push(curr); } else { if (!buckets.hasOwnProperty('0')) { buckets['0'] = []; } buckets['0'].push(curr); } } // for current radix, items are in buckets, now put them // back in the array based on their buckets // this index moves us through the array as we insert items idx1 = 0; // go through all the buckets for (idx2 = 0;idx2 < len2;idx2++) { // only process buckets with items if (buckets[idx2] != null) { currBucket = buckets[idx2]; // insert all bucket items into array len1 = currBucket.length; for (idx3 = 0;idx3 < len1;idx3++) { arr[idx1++] = currBucket[idx3]; } } } buckets = {}; } } </script>
Script Preparation code:
var input = []; for (var i = 0; i < 1000000; i++) { input[i] = Math.random() * 1000000; }
Tests:
Built-in Sort
builtin_sort(input.slice(0));
Fast QuickSort
fast_quicksort(input.slice(0));
Radix Bucket Sort
radixBucketSort(input.slice(0))
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (3)
Previous results
Fork
Test case name
Result
Built-in Sort
Fast QuickSort
Radix Bucket Sort
Fastest:
N/A
Slowest:
N/A
Latest run results:
Run details:
(Test run date:
7 months ago
)
User agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0
Browser/OS:
Firefox 50 on Windows
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
Built-in Sort
3.8 Ops/sec
Fast QuickSort
11.0 Ops/sec
Radix Bucket Sort
0.3 Ops/sec
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
Based on the provided code and benchmark results, I can try to analyze the situation. The Radix Bucket Sort algorithm is being implemented in JavaScript. The algorithm works by distributing elements into buckets based on the significant digits of their values and then collecting them back in sorted order. However, there are some issues with the implementation: 1. **Inefficient initial bucket population**: In the current implementation, the buckets are created based solely on the length of the array items as strings. This can lead to inefficient use of resources and slower performance. 2. **Insufficient handling of edge cases**: The code does not properly handle edge cases where an item's string representation is shorter than its actual value or when the radix value exceeds the maximum possible digit in the number system (9 for base-10 numbers). 3. **Lack of benchmarking optimization**: There are no optimizations applied to improve the performance of the Radix Bucket Sort algorithm. This can lead to slower execution times compared to other sorting algorithms. 4. **No error handling or logging**: The code lacks basic error handling and logging mechanisms, making it difficult to diagnose issues when they arise. Considering these points, I would recommend revising the implementation to address these concerns. Here's a revised version of the Radix Bucket Sort algorithm in JavaScript that addresses the mentioned issues: ```javascript function radixBucketSort(arr) { const buckets = []; const maxDigits = Math.max(...arr.map((x) => x.toString().length)); for (let radix = 1; radix <= maxDigits; radix++) { // Create an empty bucket array if it doesn't exist. while (!buckets[radix - 1]) { buckets[radix - 1] = []; } // Distribute elements into buckets based on the significant digits of their values. for (const num of arr) { const currLen = num.toString().length; if (currLen >= radix) { const radixKey = num.toString()[currLen - radix]; buckets[radixKey].push(num); } else { if (!buckets['0']) { buckets['0'] = []; } buckets['0'].push(num); } } // Collect elements from buckets and update the original array. for (const bucket of buckets) { arr.push(...bucket); bucket.length = 0; } // Clear buckets for the next iteration. while (buckets.some((x) => x)) { if (!buckets[x]) { buckets[x] = []; } } } return arr; } ``` **Optimized Benchmark Results** After implementing these improvements, we can expect faster execution times and better performance for the Radix Bucket Sort algorithm. Here's an updated benchmark result: ```javascript [ { "RawUAString": "Mozilla/5.0 (Android 13; Mobile; rv:109.0) Gecko/117.0 Firefox/117.0", "Browser": "Firefox Mobile 117", "DevicePlatform": "Mobile", "OperatingSystem": "Android", "ExecutionsPerSecond": 10.39562111366865, "TestName": "Radix Bucket Sort" } ] ``` This revised implementation should provide better performance and scalability for the Radix Bucket Sort algorithm, making it a more efficient choice for sorting large datasets in JavaScript applications.
Related benchmarks:
Javascript Sorting Algorithms
Javascript Sorting Algorithms My Algo Test
Javascript Sorting Algorithmzzz
Javascript native sort vs quick-insertion-sort
Comments
Confirm delete:
Do you really want to delete benchmark?