<script src="https://cdn.jsdelivr.net/underscorejs/1.5.1/underscore-min.js"></script>
<script>window.underscore = _.noConflict()</script>
<script src="https://cdn.jsdelivr.net/lodash/3.10.1/lodash.min.js"></script>
<script>window.lodash = _.noConflict()</script>
var base = {};
base.deepEquals = function(a, b) {
if (typeof a != typeof b) {
return false;
}
if (typeof a != "object") {
return a == b;
}
if (a instanceof Array) {
if (!(b instanceof Array)) {
return false;
}
if (a.length != b.length) {
return false;
}
for (var i = 0; i < a.length; i++) {
if (!base.deepEquals(a[i], b[i])) {
return false;
}
}
return true;
}
var aKeyCount = 0;
for (var key in a) {
aKeyCount++;
if (!(key in b)) {
return false;
}
if (!base.deepEquals(a[key], b[key])) {
return false;
}
}
var bKeyCount = 0;
for (var key in b) {
if (!(key in a)) {
return false;
}
bKeyCount++;
}
return aKeyCount == bKeyCount;
};
Object.prototype.equals = function (x, deep) {
if (deep) {
if (x == this) return true;
var p;
for (p in this) {
if (typeof (x[p]) == 'undefined') { return false; }
}
for (p in this) {
if (this[p]) {
switch (typeof (this[p])) {
case 'object':
if (!this[p].equals(x[p])) { return false; } break;
case 'function':
if (typeof (x[p]) == 'undefined' ||
(p != 'equals' && this[p].toString() != x[p].toString()))
return false;
break;
default:
if (this[p] != x[p]) { return false; }
}
} else {
if (x[p])
return false;
}
}
for (p in x) {
if (typeof (this[p]) == 'undefined') { return false; }
}
return true;
}
return x == this;
}
base.stringifyEquals = function(a, b) {
return JSON.stringify(a) === JSON.stringify(b);
};
a = {
tableHeight: 50,
topOffsets: [1, 2, 3, 4, 5]
};
b = {
tableHeight: 50,
topOffsets: [1, 2, 3, 4, 5]
};
base.deepEquals(a, b)
base.stringifyEquals(a, b)
a.equals(b, true)
lodash.isEqual(a,b)
underscore.isEqual(a,b)
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
deepEquals | |
stringifyEquals | |
Object.prototype.equals | |
Lodash isEqual | |
underscore isequal |
Test name | Executions per second |
---|---|
deepEquals | 380236.5 Ops/sec |
stringifyEquals | 448270.5 Ops/sec |
Object.prototype.equals | 1116419.6 Ops/sec |
Lodash isEqual | 1003513.2 Ops/sec |
underscore isequal | 621719.9 Ops/sec |
Let's dive into the world of JavaScript microbenchmarks and explore what's being tested in this benchmark.
Benchmark Definition The benchmark definition consists of four test cases, each measuring the performance of a specific equality function:
base.deepEquals(a, b)
base.stringifyEquals(a, b)
a.equals(b, true)
(using Object.prototype.equals
)lodash.isEqual(a,b)
(using Lodash)underscore.isEqual(a,b)
(using Underscore)Options Compared Each test case compares the performance of a different equality function:
base.deepEquals
and lodash.isEqual
and underscore.isEqual
compare the depth of object equality, checking if two objects have the same properties with the same values.base.stringifyEquals
compares the string representation of two objects using JSON.stringify.Pros and Cons
base.deepEquals
, lodash.isEqual
, and underscore.isEqual
use a recursive approach to compare the depth of object equality, which can lead to slower performance for large objects.base.stringifyEquals
uses JSON.stringify to compare the string representation of two objects.Lodash and Underscore Both Lodash and Underscore provide optimized equality functions that are designed to be fast and efficient. However, their implementation details may differ, affecting the performance of the benchmark.
Benchmark Results The latest benchmark results show the number of executions per second for each test case on a Mac OS X 10.15.6 machine running Chrome 85:
Object.prototype.equals
: 1116419.625 exec/seclodash.isEqual
: 1003513.1875 exec/secunderscore.isEqual
: 621719.9375 exec/secstringifyEquals
: 380236.53125 exec/secdeepEquals
: 448270.46875 exec/secOverall, the results suggest that Object.prototype.equals
is the fastest, followed by lodash.isEqual
, and then underscore.isEqual
. stringifyEquals
is significantly slower due to its simple approach.
Keep in mind that these results are specific to this particular benchmark and may not generalize to other scenarios or environments.