<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;
};
function objectsHaveSameValues(a, b, keys, recursive) {
if (_.isBoolean(keys)) {
recursive = keys;
keys = undefined;
}
if (a === b) {
return true;
}
console.log('****** not equal ', a, b);
if (b && !a || a && !b) {
return false;
}
keys = keys || _.uniq(_.keys(a).concat(_.keys(b)));
return _.every(keys, key => (recursive ? objectsHaveSameValues(a[key], b[key], true) : a[key] === b[key]));
};
// 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) => {
equal(item.value1, item.value2);
});
data.forEach((item) => {
objectsHaveSameValues(item.value1, item.value2);
});
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
fast-equal | |
customfunction |
Test name | Executions per second |
---|---|
fast-equal | 141399.4 Ops/sec |
customfunction | 18032.2 Ops/sec |
Let's break down the provided benchmark definition and explain what's being tested.
Benchmark Definition
The benchmark is testing two different approaches to compare the values of objects in JavaScript:
equal()
function: This function checks if two values are equal using the ===
operator, which performs a deep equality check for primitive values and a reference comparison for complex values like objects.objectsHaveSameValues()
function: This function is designed to compare the values of two objects recursively, taking into account nested properties.Options being compared
The benchmark is comparing the performance of these two functions in different test cases:
fast-equal
: Tests the equal()
function on an array of simple object literals.customfunction
: Tests the objectsHaveSameValues()
function on a similar array of object literals.Pros and Cons
equal()
function:objectsHaveSameValues()
function:equal()
function.Library usage
The benchmark uses the Lodash library (lodash@4.17.20
) for its _.isEqual
function, which is not explicitly mentioned in the provided code but can be inferred from the HTML preparation code. The objectsHaveSameValues()
function relies on Lodash's implementation of deep equality checking.
Latest benchmark result
The latest results show that:
equal()
function outperforms the objectsHaveSameValues()
function for simple object literals.fast-equal
test case), the objectsHaveSameValues()
function is significantly slower due to its recursive nature.Overall, the benchmark highlights the trade-offs between simplicity and accuracy in JavaScript equality checks. While the equal()
function is fast but limited in its capabilities, the objectsHaveSameValues()
function provides more comprehensive comparisons at the cost of increased computational complexity.