I needed to create an algorithm which will (efficiently) take an old array and a new array and give me back the changes between the two (which items added, which removed). It ha
I created a speed test between two possible implementations.
Source code:
function diff1 (o, n) {
// deal with empty lists
if (o == undefined) o = [];
if (n == undefined) n = [];
// sort both arrays (or this won't work)
o.sort(); n.sort();
// don't compare if either list is empty
if (o.length == 0 || n.length == 0) return {added: n, removed: o};
// declare temporary variables
var op = 0; var np = 0;
var a = []; var r = [];
// compare arrays and add to add or remove lists
while (op < o.length && np < n.length) {
if (o[op] < n[np]) {
// push to diff?
r.push(o[op]);
op++;
}
else if (o[op] > n[np]) {
// push to diff?
a.push(n[np]);
np++;
}
else {
op++;np++;
}
}
// add remaining items
if( np < n.length )
a = a.concat(n.slice(np, n.length));
if( op < o.length )
r = r.concat(o.slice(op, o.length));
return {added: a, removed: r};
}
function diff2 (o, n) {
// convert array items to object members
var objO = {}, objN = {};
for (var i = 0; i < o.length; i++) {
objO[o[i]] = 1;
}
for (var i = 0; i < n.length; i++) {
objN[n[i]] = 1;
}
var a = []; var r = [];
for (var i in objO) {
if (i in objN) {
delete objN[i];
}
else {
r.push (i);
}
}
for (var i in objN) {
a.push (i);
}
return {added: a, removed: r};
}
var o = [], n = [];
for (var i = 0; i < 300000; i++) {
if (i % 2 == 0) {
o.push (i);
}
if (i % 3 == 0) {
n.push (i);
}
}
var start = new Date ();
diff1 (o, n);
var end1 = new Date ();
diff2 (o, n);
var end2 = new Date ();
alert ((end1 - start) + ", " + (end2 - end1));
The disadvantage of diff2 that the returned arrays (added, removed) are not sorted.
Speed Test:
IE7: diff1: 2578ms, diff2: 1906ms
IE8: diff1: 1953ms, diff2: 1152ms
Firefox: diff1: 254ms, diff2: 527ms
Opera: diff1: 143ms, diff2: 253ms
Safari: diff1: 466ms, diff2: 657ms
Chrome: diff1: 734ms, diff2: 581ms
Conclusion: diff1 is faster in Firefox, Opera and Safari, diff2 is faster in IE and Chrome.