jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
function deepEqual(obj1, obj2, visited = new WeakMap()) {
if (obj1 === obj2) {
return true;
}
if (obj1 == null || obj2 == null) {
return obj1 === obj2;
}
if (typeof obj1 !== typeof obj2) {
return false;
}
if (obj1 instanceof Date && obj2 instanceof Date) {
return obj1.getTime() === obj2.getTime();
}
if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
return obj1.toString() === obj2.toString();
}
if (typeof obj1 === 'function' && typeof obj2 === 'function') {
return obj1.toString() === obj2.toString();
}
if (Array.isArray(obj1) && Array.isArray(obj2)) {
if (obj1.length !== obj2.length) {
return false;
}
for (let i = 0; i < obj1.length; i++) {
if (!deepEqual(obj1[i], obj2[i], visited)) {
return false;
}
}
return true;
}
if (obj1 instanceof Map && obj2 instanceof Map) {
if (obj1.size !== obj2.size) {
return false;
}
for (const [key, value] of obj1) {
if (!obj2.has(key) || !deepEqual(value, obj2.get(key), visited)) {
return false;
}
}
return true;
}
if (obj1 instanceof Set && obj2 instanceof Set) {
if (obj1.size !== obj2.size) {
return false;
}
for (const item of obj1) {
if (!obj2.has(item)) {
return false;
}
}
return true;
}
if (ArrayBuffer.isView(obj1) && ArrayBuffer.isView(obj2)) {
if (obj1.byteLength !== obj2.byteLength) {
return false;
}
return Array.prototype.every.call(obj1, (val, i) => val === obj2[i]);
}
if (typeof obj1 === 'object') {
if (visited.has(obj1)) {
return visited.get(obj1) === obj2;
}
visited.set(obj1, obj2);
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) {
return false;
}
for (const key of keys1) {
if (!keys2.includes(key)) {
return false;
}
if (!deepEqual(obj1[key], obj2[key], visited)) {
return false;
}
}
return true;
}
return false;
}
function generateRandomObject(objectSize, maxDepth) {
const KB = 1024;
const targetSize = objectSize * KB;
let currentSize = 0;
function getRandomKey() {
return Math.random().toString(36).substring(2, 15);
}
function getRandomPrimitive() {
const primitives = [
Math.random().toString(36).substring(2, 15), // string
Math.floor(Math.random() * 100), // number
Math.random() < 0.5, // boolean
null // null
];
return primitives[Math.floor(Math.random() * primitives.length)];
}
function getRandomValue(depth) {
if (depth >= maxDepth) {
return getRandomPrimitive();
}
const types = ['object', 'array', 'primitive'];
const type = types[Math.floor(Math.random() * types.length)];
switch (type) {
case 'object':
return generateRandomObjectHelper(depth + 1);
case 'array':
return Array.from({ length: Math.floor(Math.random() * 5) + 1 }, () => getRandomValue(depth + 1));
case 'primitive':
return getRandomPrimitive();
}
}
function generateRandomObjectHelper(depth) {
const obj = {};
while (currentSize < targetSize) {
for (let i = 0; i < 10; i++) { // Increase the number of keys per level
const key = getRandomKey();
const value = getRandomValue(depth);
obj[key] = value;
currentSize += key.length + JSON.stringify(value).length;
if (currentSize >= targetSize) break;
}
}
return obj;
}
return generateRandomObjectHelper(0);
}
var smallObj = generateRandomObject(1, 3);
var smallObjCpy = _.cloneDeep(smallObj)
var smallObj2 = generateRandomObject(1, 3);
var medObj = generateRandomObject(3, 6);
var medObjCpy = _.cloneDeep(medObj)
var medObj2 = generateRandomObject(3, 6);
var largeObj = generateRandomObject(5, 8);
var largeObjCpy = _.cloneDeep(largeObj)
var largeObj2 = generateRandomObject(5, 8);
Ready to run.
Test | Ops/sec | |
---|---|---|
Lodash isEqual - Small (Equal) |
| ready |
Vanilla deepEqual - Small (Equal) |
| ready |
Lodash isEqual - Medium (Equal) |
| ready |
Vanilla deepEqual - Medium (Equal) |
| ready |
Lodash isEqual - Large (Equal) |
| ready |
Vanilla deepEqual - Large (Equal) |
| ready |
Lodash isEqual - Small (Not equal) |
| ready |
Vanilla deepEqual - Small (Not equal) |
| ready |
Lodash isEqual - Medium (Not equal) |
| ready |
Vanilla deepEqual - Medium (Not equal) |
| ready |
Lodash isEqual - Large (Not equal) |
| ready |
Vanilla deepEqual - Large (Not equal) |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.