���θ�Υ֥饦�����οʲ������ޤ����Τǡ�����ƥ٥���ޡ����ȤäƤߤ���ʳ��ʻ��¤���

404 Blog Not Found:javascript - Array#sort������quicksort����٤�!?
Firefox 2�˴ؤ��ƤϤۤ�Ʊ��������Mac IE 5, Safari 2.0.4, Opera 9.02�Ǥ�builtin������®���ä������������κ��ϺǤ��礭���ä�Safari�Ǥ�3�����٤ǡ�builtin�Ȥ��ƤϤ�Ϥ��٤��褦�˸����롣

���졢10�����Ǥ�array��10�󥽡��Ȥ�������Chrome�η�̡�

builtin:        2389ms
quick_iter:     1827ms
quick_recur:    1848ms
merge_iter:     2316ms
merge_recur:    7058ms
benchmark-on-iphone

¿���Υɥ�եȤϤ���Τ����ɡ��ӥ�ȥ�����Ƶ��Ǥ����ǤϤʤ��Ƶ��ǤΥ����å������Ȥ���ͭ�դ��٤��ʤ롣���ǿ����礭������礭���ۤɤ��η��������ޤ�ߤ�����

���ʤߤˡ�¾�Υ֥饦�����Ǥϡ�IE 7, Safari 3.2.1, Firefox 3.0.6, Opera 9.63 �Τ������ӥ�ȥ��󤬰���®���ä���

���ʤߤ� Safari 4 �η�̡�����Ū�˺�®��

builtin:         350ms
quick_iter:      885ms
quick_recur:    1246ms
merge_iter:     1505ms
merge_recur:    5449ms

�ʲ�����ʬ�ǥ٥�����ޡ��������褦�ˤ��Ƥ����ޤ������ޤ��礭�ʿ����������ȡ��֥饦�����Υ����ɥ륿���ޡ����ܤ����ǽ��������Τǡ������Ϥɤ���⾮����ˤ��Ƥ���ޤ���100000 * 10�Ȥ��ϡ�Safari 4��Chrome�ʳ��Ϥ��Ƥ����������褤�Ǥ��礦��

�ɵ�:���ʤߤ�iPhone�Ǥ⤳���̤�ư���ޤ������٤��Τ�ư���ʤ����Ȼפä����äѤ������ư�����Ȥ�����

Dan the JavaScripter

# of Items: # of Repeats:

���̤δؿ�

middle = function(h, t){ 
    return h + ((t - h) >>> 1)
};
cmp_number = function(a, b){
    return a - b;
}

�����Ȥμ����Ǥ褯�Ѥ�����ؿ��Ǥ���

�ӥ�ȥ���

builtinsort = function(ary, cmp){
    return ary.slice().sort(cmp || cmp_number);
};

�Ƶ��ǥ����å�������

quicksort_r = function(ary, cmp){
    var ret = ary.slice();
    if (! cmp ) cmp = cmp_number;
    return (function q(head, tail) {
        var pivot = ret[middle(head, tail)];
        var i = head - 1;
        var j = tail + 1;
        while (1){
            while (cmp(ret[++i], pivot) < 0);
            while (cmp(ret[--j], pivot) > 0);
            if (i >= j) break;
            var tmp = ret[i]; ret[i] = ret[j]; ret[j] = tmp;
        }
        if (head < i - 1) arguments.callee(head, i - 1);
        if (j + 1 < tail) arguments.callee(j + 1, tail);
        return ret;
    })(0, ary.length - 1);
}

��Ƶ��ǥ����å�������

quicksort_i = function(ary, cmp){
    var ret = ary.slice();
    if (! cmp ) cmp = cmp_number;
    var stack = [ 0, ary.length - 1 ];
    while(stack.length){
        var tail = stack.pop();
        var head = stack.pop();
        var pivot = ret[middle(head, tail)];
        var i = head - 1;
        var j = tail + 1;
        while (1){
            while (cmp(ret[++i], pivot) < 0);
            while (cmp(ret[--j], pivot) > 0);
            if (i >= j) break;
            var tmp = ret[i]; ret[i] = ret[j]; ret[j] = tmp;
        }
        if (head < i - 1) { stack.push(head); stack.push(i - 1); }
        if (j + 1 < tail) { stack.push(j + 1); stack.push(tail); }
    }
    return ret;
}

�Ƶ��ǥޡ���������

(function(){

var merge = function(a, b, cmp){
    if (! cmp ) cmp = cmp_number;
    var i = 0, j = 0, k = 0;
    var li = a.length, lj = b.length;
    var ret = [];
    while(i < li && j < lj){
        ret[ret.length] = cmp(a[i],b[j]) <= 0 ? a[i++] : b[j++];
    }
    while(i < li) ret[ret.length] = a[i++];
    while(j < lj) ret[ret.length] = b[j++];
    return ret;
}

mergesort_r = function(ary, cmp){
    if (! cmp ) cmp = cmp_number;
    return (function(a){
        if (a.length <= 1) return a;
        var mid  = middle(0, a.length-1);
        var head = a.slice(0, mid+1); 
        var tail = a.slice(mid+1, a.length);
        return merge(arguments.callee(head), arguments.callee(tail), cmp)
    })(ary);
};

})();

��Ƶ��ǥޡ���������

(function(){

var work = [];
var merge_inplace = function(ary, head, mid, tail, cmp){
    if (! cmp ) cmp = cmp_number;
    var h = tail - head + 1;
    for (var i = head, j = 0; i <= tail; i++, j++) work[j] = ary[i];
    if (mid > tail) mid = middle(head, tail);
    var t = mid - head + 1;
    for (var i = head, j = 0, k = t; i <= tail; i++){
        ary[i] = 
            j < t && (k == h || cmp(work[j], work[k]) <= 0) ?
            work[j++] : work[k++];
    }
};

mergesort_i = function(ary, cmp){
    if (! cmp ) cmp = cmp_number;
    var ret = ary.slice();
    var l   = ret.length;
    var lt2 = l * 2;
    var lm1 = l - 1;
    work.length = l;
    for (var s = 2; s < lt2; s *= 2){
        for (var head = 0; head < l; head += s){
            var tail = head + s - 1;
            merge_inplace(ret, 
                          head, 
                          middle(head, tail), 
                          tail < l ? tail : l-1, 
                          cmp);
        }
    }
    return ret;
};

})();