Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
(JSON.stringify vs lodash vs fast-deep-equal vs fast-equals) with React and Promises
(version: 1)
Comparing performance of:
JSON.stringify vs lodash.isEqual vs fast-deep-equal vs fast-equals
Created:
3 years ago
by:
Registered User
Jump to the latest result
HTML Preparation code:
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/fast-equals@3.0.0/dist/fast-equals.min.js"></script> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
Script Preparation code:
function fastDeepEqual(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 (!fastDeepEqual(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 (!fastDeepEqual(a[key], b[key])) return false; } return true; } // true if both NaN, false otherwise return a !== a && b !== b; }; const fn = () => {}; const promise = Promise.resolve('foo'); var tests = [ { description: 'primitives', tests: [ { deepEqual: true, description: 'equal numbers', shallowEqual: true, value1: 1, value2: 1, }, { deepEqual: false, description: 'not equal numbers', shallowEqual: false, value1: 1, value2: 2, }, { deepEqual: true, description: 'equal zero', shallowEqual: true, value1: 0, value2: 0, }, { deepEqual: true, description: 'equal positive and negative zero', shallowEqual: true, value1: -0, value2: 0, }, { deepEqual: true, description: 'equal Infinity', shallowEqual: true, value1: Infinity, value2: Infinity, }, { deepEqual: false, description: 'not equal Infinity', shallowEqual: false, value1: -Infinity, value2: Infinity, }, { deepEqual: true, description: 'equal number objects', shallowEqual: true, value1: new Number(1), value2: new Number(1), }, { deepEqual: false, description: 'not equal number objects', shallowEqual: false, value1: new Number(1), value2: new Number(2), }, { deepEqual: false, description: 'number and array are not equal', shallowEqual: false, value1: 1, value2: [], }, { deepEqual: false, description: '0 and null are not equal', shallowEqual: false, value1: 0, value2: null, }, { deepEqual: true, description: 'NaN and NaN are equal', shallowEqual: true, value1: NaN, value2: NaN, }, { deepEqual: true, description: 'equal strings', shallowEqual: true, value1: 'a', value2: 'a', }, { deepEqual: false, description: 'not equal strings', shallowEqual: false, value1: 'a', value2: 'b', }, { deepEqual: true, description: 'equal string objects', shallowEqual: true, value1: new String('foo'), value2: new String('foo'), }, { deepEqual: false, description: 'not equal string objects', shallowEqual: false, value1: new String('foo'), value2: new String('bar'), }, { deepEqual: false, description: 'empty string and null are not equal', shallowEqual: false, value1: '', value2: null, }, { deepEqual: true, description: 'null is equal to null', shallowEqual: true, value1: null, value2: null, }, { deepEqual: true, description: 'equal booleans (true)', shallowEqual: true, value1: true, value2: true, }, { deepEqual: true, description: 'equal booleans (false)', shallowEqual: true, value1: false, value2: false, }, { deepEqual: true, description: 'equal boolean objects (true)', shallowEqual: true, value1: new Boolean(true), value2: new Boolean(true), }, { deepEqual: true, description: 'equal boolean objects (false)', shallowEqual: true, value1: new Boolean(false), value2: new Boolean(false), }, { deepEqual: false, description: 'not equal booleans', shallowEqual: false, value1: true, value2: false, }, { deepEqual: false, description: 'not equal boolean objects', shallowEqual: false, value1: new Boolean(true), value2: new Boolean(false), }, { deepEqual: false, description: '1 and true are not equal', shallowEqual: false, value1: 1, value2: true, }, { deepEqual: false, description: '0 and false are not equal', shallowEqual: false, value1: 0, value2: false, }, ], }, { description: 'functions', tests: [ { deepEqual: true, description: 'function and the same function are equal', shallowEqual: true, value1: fn, value2: fn, }, { deepEqual: false, description: 'function and different function are not equal', shallowEqual: false, value1: fn, value2: () => {}, }, ], }, { description: 'objects', tests: [ { deepEqual: true, description: 'empty objects are equal', shallowEqual: true, value1: {}, value2: {}, }, { deepEqual: true, description: 'equal objects (same properties "order")', shallowEqual: true, value1: { a: 1, b: '2', }, value2: { a: 1, b: '2', }, }, { deepEqual: true, description: 'equal objects (different properties "order")', shallowEqual: true, value1: { a: 1, b: '2', }, value2: { a: 1, b: '2', }, }, { deepEqual: false, description: 'not equal objects (extra property)', shallowEqual: false, value1: { a: 1, b: '2', }, value2: { a: 1, b: '2', c: [], }, }, { deepEqual: false, description: 'not equal objects (different properties)', shallowEqual: false, value1: { a: 1, b: '2', c: 3, }, value2: { a: 1, b: '2', d: 3, }, }, { deepEqual: false, description: 'not equal objects (different properties)', shallowEqual: false, value1: { a: 1, b: '2', c: 3, }, value2: { a: 1, b: '2', d: 3, }, }, { deepEqual: true, description: 'equal objects (same sub-properties)', shallowEqual: false, value1: { a: [{ b: 'c' }] }, value2: { a: [{ b: 'c' }] }, }, { deepEqual: false, description: 'not equal objects (different sub-property value)', shallowEqual: false, value1: { a: [{ b: 'c' }] }, value2: { a: [{ b: 'd' }] }, }, { deepEqual: false, description: 'not equal objects (different sub-property)', shallowEqual: false, value1: { a: [{ b: 'c' }] }, value2: { a: [{ c: 'c' }] }, }, { deepEqual: false, description: 'empty array and empty object are not equal', shallowEqual: false, value1: {}, value2: [], }, { deepEqual: false, description: 'object with extra undefined properties are not equal #1', shallowEqual: false, value1: {}, value2: { foo: undefined }, }, { deepEqual: false, description: 'object with extra undefined properties are not equal #2', shallowEqual: false, value1: { foo: undefined }, value2: {}, }, { deepEqual: false, description: 'object with extra undefined properties are not equal #3', shallowEqual: false, value1: { foo: undefined }, value2: { bar: undefined }, }, ], }, { description: 'arrays', tests: [ { deepEqual: true, description: 'two empty arrays are equal', shallowEqual: true, value1: [], value2: [], }, { deepEqual: true, description: 'equal arrays', shallowEqual: true, value1: [1, 2, 3], value2: [1, 2, 3], }, { deepEqual: false, description: 'not equal arrays (different item)', shallowEqual: false, value1: [1, 2, 3], value2: [1, 2, 4], }, { deepEqual: false, description: 'not equal arrays (different length)', shallowEqual: false, value1: [1, 2, 3], value2: [1, 2], }, { deepEqual: true, description: 'equal arrays of objects', shallowEqual: false, value1: [{ a: 'a' }, { b: 'b' }], value2: [{ a: 'a' }, { b: 'b' }], }, { deepEqual: false, description: 'not equal arrays of objects', shallowEqual: false, value1: [{ a: 'a' }, { b: 'b' }], value2: [{ a: 'a' }, { b: 'c' }], }, { deepEqual: false, description: 'pseudo array and equivalent array are not equal', shallowEqual: false, value1: { 0: 0, 1: 1, length: 2, }, value2: [0, 1], }, ], }, { description: 'dates', tests: [ { deepEqual: true, description: 'equal date objects', shallowEqual: true, value1: new Date('2017-06-16T21:36:48.362Z'), value2: new Date('2017-06-16T21:36:48.362Z'), }, { deepEqual: false, description: 'not equal date objects', shallowEqual: false, value1: new Date('2017-06-16T21:36:48.362Z'), value2: new Date('2017-01-01T00:00:00.000Z'), }, { deepEqual: false, description: 'date and string are not equal', shallowEqual: false, value1: new Date('2017-06-16T21:36:48.362Z'), value2: '2017-06-16T21:36:48.362Z', }, { deepEqual: false, description: 'date and object are not equal', shallowEqual: false, value1: new Date('2017-06-16T21:36:48.362Z'), value2: {}, }, { deepEqual: true, description: 'invalid dates are equal', shallowEqual: true, value1: new Date('foo'), value2: new Date('bar'), }, ], }, { description: 'regexps', tests: [ { deepEqual: true, description: 'equal RegExp objects', shallowEqual: true, value1: /foo/, value2: /foo/, }, { deepEqual: false, description: 'not equal RegExp objects (different pattern)', shallowEqual: false, value1: /foo/, value2: /bar/, }, { deepEqual: false, description: 'not equal RegExp objects (different flags)', shallowEqual: false, value1: /foo/g, value2: /foo/i, }, { deepEqual: true, description: 'equal RegExp objects (different flags "order")', shallowEqual: true, value1: new RegExp('foo', 'gi'), value2: new RegExp('foo', 'ig'), }, { deepEqual: false, description: 'RegExp and string are not equal', shallowEqual: false, value1: /foo/, value2: 'foo', }, { deepEqual: false, description: 'RegExp and object are not equal', shallowEqual: false, value1: /foo/, value2: {}, }, ], }, { description: 'maps', tests: [ { deepEqual: true, description: 'equal Map objects', shallowEqual: true, value1: new Map().set('foo', 'bar'), value2: new Map().set('foo', 'bar'), }, { deepEqual: false, description: 'not equal Map objects (different value)', shallowEqual: false, value1: new Map().set('foo', 'bar'), value2: new Map().set('foo', 'baz'), }, { deepEqual: false, description: 'not equal Map objects (different key)', shallowEqual: false, value1: new Map().set('foo', 'bar'), value2: new Map().set('baz', 'bar'), }, { deepEqual: false, description: 'not equal Map objects (same keys / values, different pairings)', shallowEqual: false, value1: new Map().set('foo', 'bar'), value2: new Map().set('bar', 'foo'), }, { deepEqual: true, description: 'deep equal Map objects', shallowEqual: false, value1: new Map().set('foo', new Map().set('bar', 'baz')), value2: new Map().set('foo', new Map().set('bar', 'baz')), }, { deepEqual: false, description: 'Map and object are not equal', shallowEqual: false, value1: new Map().set('foo', 'bar'), value2: { foo: 'bar' }, }, { deepEqual: false, description: 'Map and Set are not equal', shallowEqual: false, value1: new Map().set('foo', 'foo'), value2: new Set().add('foo'), }, ], }, { description: 'sets', tests: [ { deepEqual: true, description: 'equal Set objects', shallowEqual: true, value1: new Set().add('foo'), value2: new Set().add('foo'), }, { deepEqual: false, description: 'not equal Set objects (different value)', shallowEqual: false, value1: new Set().add('foo'), value2: new Set().add('bar'), }, { deepEqual: true, description: 'deep equal Set objects', shallowEqual: false, value1: new Set().add({ foo: 'bar' }), value2: new Set().add({ foo: 'bar' }), }, { deepEqual: false, description: 'Set and array are not equal', shallowEqual: false, value1: new Set().add('foo'), value2: ['foo'], }, ], }, { description: 'promises', tests: [ { deepEqual: true, description: 'promises are equal when strictly equal', shallowEqual: true, value1: promise, value2: promise, }, { deepEqual: false, description: 'promises are not equal when not strictly equal', shallowEqual: false, value1: promise, value2: Promise.resolve('foo'), }, ], }, { description: 'react', tests: [ { deepEqual: true, description: 'simple react elements are deeply equal', shallowEqual: false, value1: React.createElement('div', {}, 'foo'), value2: React.createElement('div', {}, 'foo'), }, { deepEqual: false, description: 'simple react elements are not deeply equal', shallowEqual: false, value1: React.createElement('div', {}, 'foo'), value2: React.createElement('div', {}, 'bar'), }, ], }, { description: 'mixed objects equal', tests: [ { deepEqual: true, description: 'big object', shallowEqual: false, value1: { prop1: 'value1', prop2: fn, prop3: null, prop4: { subProp1: 'sub value1', subProp2: { subSubProp1: 'sub sub value1', subSubProp2: [ 1, 2, { prop: 2, prop2: 1, }, 4, 5, ], }, }, prop5: 1000, prop6: new Date(2016, 2, 10), prop7: /foo/, }, value2: { prop1: 'value1', prop2: fn, prop3: null, prop4: { subProp1: 'sub value1', subProp2: { subSubProp1: 'sub sub value1', subSubProp2: [ 1, 2, { prop: 2, prop2: 1, }, 4, 5, ], }, }, prop5: 1000, prop6: new Date(2016, 2, 10), prop7: /foo/, }, }, ], }, { description: 'mixed objects not equal', tests: [ { deepEqual: false, description: 'big object', shallowEqual: false, value1: { prop1: 'value1', prop2: fn, prop3: null, prop4: { subProp1: 'sub value1', subProp2: { subSubProp1: 'sub sub value1', subSubProp2: [ 1, 2, { prop: 2, prop2: 1, }, 4, 5, ], }, }, prop5: 1000, prop6: new Date(2016, 2, 10), prop7: /foo/, }, value2: { prop1: 'value1', prop2: fn, prop3: null, prop4: { subProp1: 'sub value1', subProp2: { subSubProp1: 'sub sub value1', subSubProp2: [ 1, 2, { prop: 2, prop2: 1, }, 4, 5, ], }, }, prop5: 1000, prop6: new Date('2017/04/17'), prop7: /foo/, }, }, ], }, ]; function runTests(equalFunc) { for (const testSuite of tests) { for (const test of testSuite.tests) { if (test.description != 'pseudo array and equivalent array are not equal') equalFunc(test.value1, test.value2); } } }
Tests:
JSON.stringify
runTests(function(a, b) {JSON.stringify(a) === JSON.stringify(b)})
lodash.isEqual
runTests(_.isEqual)
fast-deep-equal
runTests(fastDeepEqual)
fast-equals
runTests(window["fast-equals"].deepEqual)
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (4)
Previous results
Fork
Test case name
Result
JSON.stringify
lodash.isEqual
fast-deep-equal
fast-equals
Fastest:
N/A
Slowest:
N/A
Latest run results:
Run details:
(Test run date:
one year ago
)
User agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Browser/OS:
Chrome 126 on Windows
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
JSON.stringify
34585.3 Ops/sec
lodash.isEqual
34307.2 Ops/sec
fast-deep-equal
39627.9 Ops/sec
fast-equals
182052.7 Ops/sec
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
I'll do my best to extract the relevant information from the provided text. **Benchmark Results:** The latest benchmark results show that: * `fast-equals` has an execution rate of 182,052.6875 executions per second * `fast-deep-equal` has an execution rate of 39,627.87890625 executions per second * `JSON.stringify` has an execution rate of 34,535.2734375 executions per second * `lodash.isEqual` has an execution rate of 34,307.23828125 executions per second **Individual Test Cases:** The individual test cases are: 1. **"JSON.stringify"**: A test case for the `fast-equals` library's stringification function. 2. **"lodash.isEqual"**: A test case for the `lodash` library's `isEqual` function. 3. **"fast-deep-equal"**: A test case for the `fast-equals` library's deep equality function. 4. **"fast-equals"**: The same test case as above, but using the native `window["fast-equals"]` property. **Browser and Device Information:** The latest benchmark results were run on: * Browser: Chrome 126 * Device Platform: Desktop * Operating System: Windows
Related benchmarks:
Test on isEqual and fastEqual false performance
fast compare test w/lodash 3
react-fast-compare vs JSON.stringify Equality Comparison for Shallow Array of Strings.
Lodash.isEqual vs JSON.stringify Equality Comparison for 1000 length array
Comments
Confirm delete:
Do you really want to delete benchmark?