<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js'></script>
function equal(a, b) {
if (a === b) return true;
if (a && b && typeof a == 'object' && typeof b == 'object') {
if (a.constructor !== b.constructor) return false;
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0;)
if (!equal(a[i], b[i])) return false;
return true;
}
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
keys = Object.keys(a);
length = keys.length;
if (length !== Object.keys(b).length) return false;
for (i = length; i-- !== 0;)
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
for (i = length; i-- !== 0;) {
var key = keys[i];
if (!equal(a[key], b[key])) return false;
}
return true;
}
// true if both NaN, false otherwise
return a!==a && b!==b;
};
var tests = [
{
description: 'scalars',
tests: [
{
description: 'equal numbers',
value1: 1,
value2: 1,
equal: true
},
{
description: 'not equal numbers',
value1: 1,
value2: 2,
equal: false
},
{
description: 'number and array are not equal',
value1: 1,
value2: [],
equal: false
},
{
description: '0 and null are not equal',
value1: 0,
value2: null,
equal: false
},
{
description: 'equal strings',
value1: 'a',
value2: 'a',
equal: true
},
{
description: 'not equal strings',
value1: 'a',
value2: 'b',
equal: false
},
{
description: 'empty string and null are not equal',
value1: '',
value2: null,
equal: false
},
{
description: 'null is equal to null',
value1: null,
value2: null,
equal: true
},
{
description: 'equal booleans (true)',
value1: true,
value2: true,
equal: true
},
{
description: 'equal booleans (false)',
value1: false,
value2: false,
equal: true
},
{
description: 'not equal booleans',
value1: true,
value2: false,
equal: false
},
{
description: '1 and true are not equal',
value1: 1,
value2: true,
equal: false
},
{
description: '0 and false are not equal',
value1: 0,
value2: false,
equal: false
},
{
description: 'NaN and NaN are equal',
value1: NaN,
value2: NaN,
equal: true
},
{
description: '0 and -0 are equal',
value1: 0,
value2: -0,
equal: true
},
{
description: 'Infinity and Infinity are equal',
value1: Infinity,
value2: Infinity,
equal: true
},
{
description: 'Infinity and -Infinity are not equal',
value1: Infinity,
value2: -Infinity,
equal: false
}
]
},
{
description: 'objects',
tests: [
{
description: 'empty objects are equal',
value1: {},
value2: {},
equal: true
},
{
description: 'equal objects (same properties "order")',
value1: {a: 1, b: '2'},
value2: {a: 1, b: '2'},
equal: true
},
{
description: 'equal objects (different properties "order")',
value1: {a: 1, b: '2'},
value2: {b: '2', a: 1},
equal: true
},
{
description: 'not equal objects (extra property)',
value1: {a: 1, b: '2'},
value2: {a: 1, b: '2', c: []},
equal: false
},
{
description: 'not equal objects (different property values)',
value1: {a: 1, b: '2', c: 3},
value2: {a: 1, b: '2', c: 4},
equal: false
},
{
description: 'not equal objects (different properties)',
value1: {a: 1, b: '2', c: 3},
value2: {a: 1, b: '2', d: 3},
equal: false
},
{
description: 'equal objects (same sub-properties)',
value1: { a: [ { b: 'c' } ] },
value2: { a: [ { b: 'c' } ] },
equal: true
},
{
description: 'not equal objects (different sub-property value)',
value1: { a: [ { b: 'c' } ] },
value2: { a: [ { b: 'd' } ] },
equal: false
},
{
description: 'not equal objects (different sub-property)',
value1: { a: [ { b: 'c' } ] },
value2: { a: [ { c: 'c' } ] },
equal: false
},
{
description: 'empty array and empty object are not equal',
value1: {},
value2: [],
equal: false
},
{
description: 'object with extra undefined properties are not equal #1',
value1: {},
value2: {foo: undefined},
equal: false
},
{
description: 'object with extra undefined properties are not equal #2',
value1: {foo: undefined},
value2: {},
equal: false
},
{
description: 'object with extra undefined properties are not equal #3',
value1: {foo: undefined},
value2: {bar: undefined},
equal: false
},
{
description: 'nulls are equal',
value1: null,
value2: null,
equal: true
},
{
description: 'null and undefined are not equal',
value1: null,
value2: undefined,
equal: false
},
{
description: 'null and empty object are not equal',
value1: null,
value2: {},
equal: false
},
{
description: 'undefined and empty object are not equal',
value1: undefined,
value2: {},
equal: false
},
{
description: 'objects with different `toString` functions returning same values are equal',
value1: {toString: ()=>'Hello world!'},
value2: {toString: ()=>'Hello world!'},
equal: true
},
{
description: 'objects with `toString` functions returning different values are not equal',
value1: {toString: ()=>'Hello world!'},
value2: {toString: ()=>'Hi!'},
equal: false
}
]
},
{
description: 'arrays',
tests: [
{
description: 'two empty arrays are equal',
value1: [],
value2: [],
equal: true
},
{
description: 'equal arrays',
value1: [1, 2, 3],
value2: [1, 2, 3],
equal: true
},
{
description: 'not equal arrays (different item)',
value1: [1, 2, 3],
value2: [1, 2, 4],
equal: false
},
{
description: 'not equal arrays (different length)',
value1: [1, 2, 3],
value2: [1, 2],
equal: false
},
{
description: 'equal arrays of objects',
value1: [{a: 'a'}, {b: 'b'}],
value2: [{a: 'a'}, {b: 'b'}],
equal: true
},
{
description: 'not equal arrays of objects',
value1: [{a: 'a'}, {b: 'b'}],
value2: [{a: 'a'}, {b: 'c'}],
equal: false
},
{
description: 'pseudo array and equivalent array are not equal',
value1: {'0': 0, '1': 1, length: 2},
value2: [0, 1],
equal: false
}
]
},
{
description: 'Date objects',
tests: [
{
description: 'equal date objects',
value1: new Date('2017-06-16T21:36:48.362Z'),
value2: new Date('2017-06-16T21:36:48.362Z'),
equal: true
},
{
description: 'not equal date objects',
value1: new Date('2017-06-16T21:36:48.362Z'),
value2: new Date('2017-01-01T00:00:00.000Z'),
equal: false
},
{
description: 'date and string are not equal',
value1: new Date('2017-06-16T21:36:48.362Z'),
value2: '2017-06-16T21:36:48.362Z',
equal: false
},
{
description: 'date and object are not equal',
value1: new Date('2017-06-16T21:36:48.362Z'),
value2: {},
equal: false
}
]
},
{
description: 'RegExp objects',
tests: [
{
description: 'equal RegExp objects',
value1: /foo/,
value2: /foo/,
equal: true
},
{
description: 'not equal RegExp objects (different pattern)',
value1: /foo/,
value2: /bar/,
equal: false
},
{
description: 'not equal RegExp objects (different flags)',
value1: /foo/,
value2: /foo/i,
equal: false
},
{
description: 'RegExp and string are not equal',
value1: /foo/,
value2: 'foo',
equal: false
},
{
description: 'RegExp and object are not equal',
value1: /foo/,
value2: {},
equal: false
}
]
},
{
description: 'functions',
tests: [
{
description: 'same function is equal',
value1: func1,
value2: func1,
equal: true
},
{
description: 'different functions are not equal',
value1: func1,
value2: func2,
equal: false
}
]
},
{
description: 'sample objects',
tests: [
{
description: 'big object',
value1: {
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)
},
value2: {
prop5: 1000,
prop3: 'value3',
prop1: 'value1',
prop2: 'value2',
prop6: new Date('2016/03/10'),
prop4: {
subProp2: {
subSubProp1: 'sub sub value1',
subSubProp2: [1, 2, {prop2: 1, prop: 2}, 4, 5]
},
subProp1: 'sub value1'
}
},
equal: true
}
]
}
];
function func1() {}
function func2() {}
for (const testSuite of tests) {
for (const test of testSuite.tests) {
try {
if (equal(test.value1, test.value2) !== test.equal)
console.error('different result', 'fast-deep-equal', testSuite.description, test.description);
} catch(e) {
console.error('fast-deep-equal', testSuite.description, test.description, e);
}
}
}
for (const testSuite of tests) {
for (const test of testSuite.tests) {
try {
if (_.isEqual(test.value1, test.value2) !== test.equal)
console.error('different result', 'isEqual', testSuite.description, test.description);
} catch(e) {
console.error('isEqual', testSuite.description, test.description, e);
}
}
}
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
fast-deep-equal | |
lodash |
Test name | Executions per second |
---|---|
fast-deep-equal | 24893.4 Ops/sec |
lodash | 20243.6 Ops/sec |
Based on the provided benchmark data, I'll provide an analysis of the results:
fast-deep-equal
The test results indicate that the fast-deep-equal
benchmark is performed on a Chrome 116 browser with a desktop device and Mac OS X 10.15.7 operating system.
lodash
The test results indicate that the lodash
benchmark is performed on a Chrome 116 browser with a desktop device and Mac OS X 10.15.7 operating system.
Comparing the two results:
fast-deep-equal
benchmark has a slightly higher Executions Per Second (24,893.38 vs 20,243.62) than the lodash
benchmark.This suggests that the fast-deep-equal
benchmark may be faster or more efficient than the lodash
benchmark under these specific conditions. However, it's essential to note that this result is based on a single run and may not reflect the actual performance difference between the two implementations in all scenarios.