<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.20/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;
};
// 1 level deep
var data = [
{
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: '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,
},
];
data.forEach((item) => {
_.isEqual(item.value1, item.value2);
});
data.forEach((item) => {
equal(item.value1, item.value2);
});
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
lodash | |
fast-deep-equal |
Test name | Executions per second |
---|---|
lodash | 278138.6 Ops/sec |
fast-deep-equal | 1028518.8 Ops/sec |
I'll break down the provided benchmark definition and explain what's being tested, compared, and the pros/cons of each approach.
Benchmark Definition
The benchmark measures the performance difference between two JavaScript functions:
lodash.isEqual
(Lodash): A widely-used library for comparing values.equal
(Custom implementation): A custom function written in JavaScript.Test Cases
There are two test cases:
_.isEqual
)
The benchmark defines a script that iterates over an array of objects using the forEach
method and calls _lodash.isEqual
on each pair of value1
and value2
properties.data.forEach((item) => {
_.isEqual(item.value1, item.value2);
});
Custom Implementation (equal
)
The benchmark also defines a script that iterates over the same array of objects using forEach
and calls the custom equal
function on each pair of value1
and value2
properties.
data.forEach((item) => {
equal(item.value1, item.value2);
});
Comparison
The benchmark compares the performance of Lodash's _isEqual
function with the custom implementation (equal
). This comparison is done by executing both scripts multiple times (not specified in the provided data).
Pros and Cons
Lodash (_.isEqual
)
Pros:
Cons:
Custom Implementation (equal
)
Pros:
Cons:
Other Considerations
The benchmark also includes some additional considerations, such as:
Array.isArray()
to check if an object is an array or not.NaN
(Not a Number) values using a simple trick (a !== a && b !== b
).Object.keys()
and Object.prototype.hasOwnProperty.call()
for comparing object properties.Alternatives
If you're considering implementing your own comparison function, you may want to explore other libraries or implementations that offer similar functionality with better performance or features. Some examples include:
fast-deep-equal
(not used in this benchmark)deep-eq
(a JavaScript library for deep object equality)compare-arrays
(a polyfill for array comparison)Keep in mind that the best approach often depends on your specific use case and requirements.