Skip to content

Instantly share code, notes, and snippets.

@gamedevsam
Last active February 28, 2022 18:30
Show Gist options
  • Save gamedevsam/517b8018e60f97dd84f2ca6b0dfb1f48 to your computer and use it in GitHub Desktop.
Save gamedevsam/517b8018e60f97dd84f2ca6b0dfb1f48 to your computer and use it in GitHub Desktop.
Deep object comparison benchmark

Requires hyperfine to run: https://github.com/sharkdp/hyperfine

Run it like so: hyperfine 'node dequal.mjs' 'node md5.mjs' 'node sha1.mjs'

Results:

Summary
  'node dequal.mjs' ran
    1.16 ± 0.20 times faster than 'node md5.mjs'
    1.17 ± 0.21 times faster than 'node sha1.mjs'
export function deepEquals(foo, bar) {
let ctor, len;
if (foo === bar) {
return true;
}
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
if (ctor === Array) {
if ((len = foo.length) === bar.length) {
while (len-- && deepEquals(foo[len], bar[len])) { }
}
return len === -1;
}
if (!ctor || typeof foo === 'object') {
len = 0;
for (ctor in foo) {
if (
Object.prototype.hasOwnProperty.call(foo, ctor) &&
++len &&
!Object.prototype.hasOwnProperty.call(bar, ctor)
) {
return false;
}
if (!(ctor in bar) || !deepEquals(foo[ctor], bar[ctor])) {
return false;
}
}
return Object.keys(bar).length === len;
}
}
return foo !== foo && bar !== bar;
}
const a = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3',
prop4: {
subProp1: 'sub value1',
subProp2: {
subSubProp1: 'sub sub value1',
subSubProp2: [1, 2, { prop2: 1, prop: 2 }, 4, 5],
},
},
prop5: 1000,
prop6: new Date(2016, 2, 10).getTime(),
};
const b = {
prop5: 1000,
prop3: 'value3',
prop1: 'value1',
prop2: 'value2',
prop6: new Date('2016/03/10').getTime(),
prop4: {
subProp2: {
subSubProp1: 'sub sub value1',
subSubProp2: [1, 2, { prop2: 1, prop: 2 }, 4, 5],
},
subProp1: 'sub value1',
},
};
if (!deepEquals(a, b)) {
throw new Error();
}
import crypto from 'crypto'
const a = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3',
prop4: {
subProp1: 'sub value1',
subProp2: {
subSubProp1: 'sub sub value1',
subSubProp2: [1, 2, { prop2: 1, prop: 2 }, 4, 5],
},
},
prop5: 1000,
prop6: new Date(2016, 2, 10).getTime(),
};
const hashA = crypto.createHash('md5').update(JSON.stringify(a)).digest('base64');
const hashB = crypto.createHash('md5').update(JSON.stringify(a)).digest('base64');
if (hashA !== hashB) {
throw new Error();
}
import crypto from 'crypto'
const a = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3',
prop4: {
subProp1: 'sub value1',
subProp2: {
subSubProp1: 'sub sub value1',
subSubProp2: [1, 2, { prop2: 1, prop: 2 }, 4, 5],
},
},
prop5: 1000,
prop6: new Date(2016, 2, 10).getTime(),
};
const hashA = crypto.createHash('sha1').update(JSON.stringify(a)).digest('base64');
const hashB = crypto.createHash('sha1').update(JSON.stringify(a)).digest('base64');
if (hashA !== hashB) {
throw new Error();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment