# Natural sort

## JavaScript performance comparison

Revision 6 of this test case created by

## Preparation code

``````<script src="http://membres-liglab.imag.fr/donsez/cours/exemplescourstechnoweb/js_securehash/md5.js"></script>
<script>
function alphanum(a, b) {
function chunkify(t) {
var tz = [], x = 0, y = -1, n = 0, i, j;

while (i = (j = t.charAt(x++)).charCodeAt(0)) {
var m = (i == 46 || (i >=48 && i <= 57));
if (m !== n) {
tz[++y] = "";
n = m;
}
tz[y] += j;
}
return tz;
}

var aa = chunkify(a);
var bb = chunkify(b);

for (x = 0; aa[x] && bb[x]; x++) {
if (aa[x] !== bb[x]) {
var c = Number(aa[x]), d = Number(bb[x]);
if (c == aa[x] && d == bb[x]) {
return c - d;
} else return (aa[x] > bb[x]) ? 1 : -1;
}
}
return aa.length - bb.length;
}

Array.prototype.alphanumSort = function(caseInsensitive) {
for (var z = 0, t; t = this[z]; z++) {
this[z] = [];
var x = 0, y = -1, n = 0, i, j;

while (i = (j = t.charAt(x++)).charCodeAt(0)) {
var m = (i == 46 || (i >=48 && i <= 57));
if (m !== n) {
this[z][++y] = "";
n = m;
}
this[z][y] += j;
}
}

this.sort(function(a, b) {
for (var x = 0, aa, bb; (aa = a[x]) && (bb = b[x]); x++) {
if (caseInsensitive) {
aa = aa.toLowerCase();
bb = bb.toLowerCase();
}
if (aa !== bb) {
var c = Number(aa), d = Number(bb);
if (c == aa && d == bb) {
return c - d;
} else return (aa > bb) ? 1 : -1;
}
}
return a.length - b.length;
});

for (var z = 0; z < this.length; z++)
this[z] = this[z].join("");
}

function a1Sort(a, b){
var cnt= 0, tem;
a= String(a).toLowerCase();
b= String(b).toLowerCase();
if(a== b) return 0;
if(/\d/.test(a) ||  /\d/.test(b)){
var Rx=  /^\d+(\.\d+)?/;
while(a.charAt(cnt)=== b.charAt(cnt) &&
!Rx.test(a.substring(cnt))){
cnt++;
}
a= a.substring(cnt);
b= b.substring(cnt);
if(Rx.test(a) || Rx.test(b)){
if(!Rx.test(a)) return a? 1: -1;
if(!Rx.test(b)) return b? -1: 1;
tem= parseFloat(a)-parseFloat(b);
if(tem!= 0) return tem;
a= a.replace(Rx,'');
b= b.replace(Rx,'');
if(/\d/.test(a) ||  /\d/.test(b)){
return a1Sort(a, b);
}
}
}
if(a== b) return 0;
return a> b? 1: -1;
}

// https://github.com/litejs/natural-compare-lite/
String.naturalCompare = function(a, b) {

if (a != b) for (var c, ca = 1, cb, i, ia = 0, ib = 0; ca;) {
ca = a.charCodeAt(ia++) || 0
cb = b.charCodeAt(ib++) || 0

i = -1

if (ca < 58 && ca > 47) {
for (i = ia - 1; c = a.charCodeAt(ia), c < 58 && c > 47; ia++);
}

if (cb < 58 && cb > 47) {
// number always comes first
if (i == -1) return 1
ca = a.slice(i, ia)|0
for (i = ib - 1; c = b.charCodeAt(ib), c < 58 && c > 47; ib++);
cb = b.slice(i, ib)|0
} else if (i > -1) return -1

if (ca > cb) return 1
if (ca < cb) return -1
}
return 0
}

var bbb = [];
for (var iii = 0; iii < 1000; ++iii)
{
bbb.push(calcMD5(iii.toString()));
}
</script>
<script src="https://raw.github.com/kvz/phpjs/master/functions/strings/strnatcasecmp.js"></script>
<script src="https://raw.github.com/kvz/phpjs/master/functions/array/natcasesort.js"></script>

<script>
Benchmark.prototype.setup = function() {
var aaa = bbb.slice(0);
};

</script>
``````

## Preparation code output

<script> function alphanum(a, b) { function chunkify(t) { var tz = [], x = 0, y = -1, n = 0, i, j; while (i = (j = t.charAt(x++)).charCodeAt(0)) { var m = (i == 46 || (i >=48 && i <= 57)); if (m !== n) { tz[++y] = ""; n = m; } tz[y] += j; } return tz; } var aa = chunkify(a); var bb = chunkify(b); for (x = 0; aa[x] && bb[x]; x++) { if (aa[x] !== bb[x]) { var c = Number(aa[x]), d = Number(bb[x]); if (c == aa[x] && d == bb[x]) { return c - d; } else return (aa[x] > bb[x]) ? 1 : -1; } } return aa.length - bb.length; } Array.prototype.alphanumSort = function(caseInsensitive) { for (var z = 0, t; t = this[z]; z++) { this[z] = []; var x = 0, y = -1, n = 0, i, j; while (i = (j = t.charAt(x++)).charCodeAt(0)) { var m = (i == 46 || (i >=48 && i <= 57)); if (m !== n) { this[z][++y] = ""; n = m; } this[z][y] += j; } } this.sort(function(a, b) { for (var x = 0, aa, bb; (aa = a[x]) && (bb = b[x]); x++) { if (caseInsensitive) { aa = aa.toLowerCase(); bb = bb.toLowerCase(); } if (aa !== bb) { var c = Number(aa), d = Number(bb); if (c == aa && d == bb) { return c - d; } else return (aa > bb) ? 1 : -1; } } return a.length - b.length; }); for (var z = 0; z < this.length; z++) this[z] = this[z].join(""); } function a1Sort(a, b){ var cnt= 0, tem; a= String(a).toLowerCase(); b= String(b).toLowerCase(); if(a== b) return 0; if(/\d/.test(a) || /\d/.test(b)){ var Rx= /^\d+(\.\d+)?/; while(a.charAt(cnt)=== b.charAt(cnt) && !Rx.test(a.substring(cnt))){ cnt++; } a= a.substring(cnt); b= b.substring(cnt); if(Rx.test(a) || Rx.test(b)){ if(!Rx.test(a)) return a? 1: -1; if(!Rx.test(b)) return b? -1: 1; tem= parseFloat(a)-parseFloat(b); if(tem!= 0) return tem; a= a.replace(Rx,''); b= b.replace(Rx,''); if(/\d/.test(a) || /\d/.test(b)){ return a1Sort(a, b); } } } if(a== b) return 0; return a> b? 1: -1; } // https://github.com/litejs/natural-compare-lite/ String.naturalCompare = function(a, b) { if (a != b) for (var c, ca = 1, cb, i, ia = 0, ib = 0; ca;) { ca = a.charCodeAt(ia++) || 0 cb = b.charCodeAt(ib++) || 0 i = -1 if (ca < 58 && ca > 47) { for (i = ia - 1; c = a.charCodeAt(ia), c < 58 && c > 47; ia++); } if (cb < 58 && cb > 47) { // number always comes first if (i == -1) return 1 ca = a.slice(i, ia)|0 for (i = ib - 1; c = b.charCodeAt(ib), c < 58 && c > 47; ib++); cb = b.slice(i, ib)|0 } else if (i > -1) return -1 if (ca > cb) return 1 if (ca < cb) return -1 } return 0 } var bbb = []; for (var iii = 0; iii < 1000; ++iii) { bbb.push(calcMD5(iii.toString())); } </script> <script src="https://raw.github.com/kvz/phpjs/master/functions/strings/strnatcasecmp.js"></script> <script src="https://raw.github.com/kvz/phpjs/master/functions/array/natcasesort.js"></script>

## Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
alphanum
``aaa.sort(alphanum);``
pending…
alphanumSort
``aaa.alphanumSort();``
pending…
a1sort
``aaa.sort(a1Sort);``
pending…
natcasesort
``natcasesort(aaa);``
pending…
String.naturalCompare
``````// https://github.com/litejs/natural-compare-lite/
aaa.sort(String.naturalCompare);``````
pending…

## Revisions

You can edit these tests or add even more tests to this page by appending `/edit` to the URL.