Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

By "fastest", I mean runs with the best time on most/all popular web browsers. For explicitness lets say the latest and second latest version of IE, FF, Chrome and Safari.

By "integer", I mean a 32bit signed integer.

Currently I'm under the impression that Radix Sort is the fastest algorithm for this job. I've created a small benchmark page which you can insert your implementation (of whatever sorting algorithm you think is faster) into for testing.

I am * not * looking for micro-optimizations (yet) like loop unrolling, smaller variable names (JS minimization), etc.

I am * not * interested in theories about sorting or personal anecdotes regarding your experiences with sorting.

The use-case I'm interested in is arrays with varying lengths from 50,000 to ~2,000,000.

I'd like fast running implementations of sorting algorithms, in the hopes of finding a definitive answer to my question.

I'm open to interesting solutions like spawning multiple browser windows and creating a sort of multi-threaded approach (and at which array length threshold that approach would tend to run faster).

<html>
<head>
<script type="text/javascript">

var _radixSort_0 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
function radixSort(intArr) {
    var cpy = new Array(intArr.length);
    var c4 = [].concat(_radixSort_0); 
    var c3 = [].concat(_radixSort_0); 
    var c2 = [].concat(_radixSort_0);
    var c1 = [].concat(_radixSort_0); 
    var o4 = 0; var t4;
    var o3 = 0; var t3;
    var o2 = 0; var t2;
    var o1 = 0; var t1;
    // get counts
    for(var x=0; x<intArr.length; x++) {
        t4 = intArr[x] & 0xFF;
        t3 = (intArr[x] >> 8) & 0xFF;
        t2 = (intArr[x] >> 16) & 0xFF;
        t1 = (intArr[x] >> 24) & 0xFF ^ 0x80;
        c4[t4]++;
        c3[t3]++;
        c2[t2]++;
        c1[t1]++;
    }
    // transform counts to pointers
    for (var x=0; x<256; x++) {
        t4 = o4 + c4[x];
        t3 = o3 + c3[x];
        t2 = o2 + c2[x];
        t1 = o1 + c1[x];
        c4[x] = o4;
        c3[x] = o3;
        c2[x] = o2;
        c1[x] = o1;
        o4 = t4;
        o3 = t3;
        o2 = t2;
        o1 = t1;
    }
    // sort array
    for(var x=0; x<intArr.length; x++) {
        t4 = intArr[x] & 0xFF;
        cpy[c4[t4]] = intArr[x];
        c4[t4]++;
    }
    for(var x=0; x<intArr.length; x++) {
        t3 = (cpy[x] >> 8) & 0xFF;
        intArr[c3[t3]] = cpy[x];
        c3[t3]++;
    }
    for(var x=0; x<intArr.length; x++) {
        t2 = (intArr[x] >> 16) & 0xFF;
        cpy[c2[t2]] = intArr[x];
        c2[t2]++;
    }
    for(var x=0; x<intArr.length; x++) {
        t1 = (cpy[x] >> 24) & 0xFF ^ 0x80;
        intArr[c1[t1]] = cpy[x];
        c1[t1]++;
    }
    return intArr;
}

function quickSort(arr)
{
    if (arr.length == 0) return [];
    // setup
    var left = new Array();
    var right = new Array();
    var pivot = arr[0];
    // quick sort
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] < pivot) {
            left.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }
    // recurse
    return quickSort(left).concat(pivot, quickSort(right));
}

function defaultSort(intArr) {

    return intArr.sort(function(a,b){return a-b;});
}

function bench(func, len) {
    var test = [];
    for(var x=0; x<len; x++) {
        test[x] = Math.floor(Math.random()*2000000000) - 1000000000;
    }
    var s = (new Date()).getTime();
    test = func(test);
    s = (new Date()).getTime() - s;
    document.getElementById('outp').innerHTML += '<br/>' + /(function )([a-z0-9]+)/i.exec(func.toString())[2] + ': ' + s; 
    for(var x=0; x<len-1; x++) {
        if(test[x] > test[x+1]) {
            alert('error');
            break;
        }
    }
}

</script>
</head>
<body>
<input type="text" id="lng" value="50000" />
<br/>
<input type="button" value="Radix Sort" onclick="bench(radixSort, parseInt(document.getElementById('lng').value));" />
<input type="button" value="Quick Sort" onclick="bench(quickSort, parseInt(document.getElementById('lng').value));" />
<input type="button" value="Array.Sort" onclick="bench(defaultSort, parseInt(document.getElementById('lng').value));" />
<br/>
<div id="outp" />
</body>
</html>
  • edit * For even more clarity
  • I am looking for JS implementations (actual JS that runs and is testable).
  • I'm well aware that an algorithm of O(n) will likely win (or a well implemented multi-threaded O(n log n) algorithm).
  • The benchmarking HTML above is so anyone can easily plug an algorithm in, it's not inferring that those are the ONLY algorithms or that Quick Sort is some how competitive to Radix Sort in this instance.
share|improve this question
3  
Why in the world would you compare quicksort to radix sort? Do you understand asymptotic complexity? Perhaps what you really need is to take a step back and realize that theory has a lot to say about the answer to this. Well-known O(n), O(n log n) and O(n^2) algorithms exist for sorting, and the necessary and sufficient conditions for correctness are given. Hybrid techniques, and those exploiting parallelism, abound. This is not a reasonable question to ask, if you intend to downvote answers you don't consider to be definitive. A definitive answer depends on too much. – Patrick87 Aug 18 '11 at 20:48
6  
Downvote whatever you want... it's your question. So you're downvoting answers that don't list the code, even if they name things to try? I can't speak for anybody else, but I feel like there's a difference between legitimate questions and asking for others to do their work for them. This smacks of the latter. – Patrick87 Aug 19 '11 at 2:54
My legitimate question is... "here's a fast integer sort in JS (refer to Radix Sort in benchmarking HTML) does a faster one exist?" Again, your just grasping at straws out of some odd sense of malice. I have a 'working' solution, but I was curious if someone had a faster/better 'working' solution. – LastCoder Aug 19 '11 at 11:13
2  
People answered that question, or were beginning to. Note that providing code isn't required to answer that question. There's not any "malice" going on here... based on your expressed desires, this is a poor question for SO, and lots of people besides me thought so. You will probably also have more luck if you leave the 'tude out of these posts... more flies with honey than with vinegar. – Patrick87 Aug 19 '11 at 13:46
1  
@Adrian Edioma Migraso - I re-asked this question and got much better answers stackoverflow.com/questions/8082425/… – LastCoder Jan 29 at 19:42
show 2 more comments

closed as not a real question by larsmans, Mark Biek, jtbandes, Andrie, Neil Knight Aug 19 '11 at 7:54

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

1 Answer

I can't imagine what's wrong with the built-in array sort method.

But if you really want to make use of multiple windows to to multiprocessing (does that even work on all browsers?), then I would say split the array, sort each segment in it's own window/thread, and then merge the sorted lists two at a time. In order words, merge 8 segments down to 4 (in 4 threads) and then merge those 4 down to 2 (int 2 threads) and then merge those 2 into 1 (in 1 thread).

share|improve this answer
I don't require a multi-threaded solution. My question explicitly asked for implementations not theory or conjecture. – LastCoder Aug 18 '11 at 19:09
3  
My answer contained an implementation: the native one that comes with JavaScript. The one that you aren't going to be able to outperform. – Fantius Aug 18 '11 at 20:54
The built in array.sort does not sort integers you have to pass it a comparison algorithm, which the benchmark HTML I provided does fyi it's slower. If you don't believe me "javascript:alert([4,20,3].sort())". – LastCoder Aug 19 '11 at 1:45
I see your point now. – Fantius Aug 19 '11 at 3:07
I should have ran your sample code in the first place (you should have hosted it somewhere). Your question statement could have been significantly simpler. Other than that, I don't know why the question was closed. – Fantius Aug 19 '11 at 12:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.