Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Run results for:
lodash merge vs deepmerge 4.2.2 vs own merge implementation
Go to the benchmark
Embed
Embed Benchmark Result
Run details:
User agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Browser:
Chrome 135
Operating system:
Windows
Device Platform:
Desktop
Date tested:
one year ago
Test name
Executions per second
lodash
309929.2 Ops/sec
deepmerge
708380.6 Ops/sec
own impl
1251469.4 Ops/sec
HTML Preparation code:
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js'></script> <script src='https://unpkg.com/deepmerge@4.2.2/dist/umd.js'></script>
Script Preparation code:
var a = { a: 'oh', b: 'my', c: { a: 'a', b: { c: 'c' } } }; var b = { c: { b: { d: 'a' }, c: { d: 'd' } } }; var c = _.merge({}, a, b);
Tests:
lodash
var a = { a: 'oh', b: 'my', c: { a: 'a', b: { c: 'c' } } }; var b = { c: { b: { d: 'a' }, c: { d: 'd' } } }; var c = _.merge({}, a, b);
deepmerge
var a = { a: 'oh', b: 'my', c: { a: 'a', b: { c: 'c' } } }; var b = { c: { b: { d: 'a' }, c: { d: 'd' } } }; var c = deepmerge({}, a, b);
own impl
function isMergable(property) { return Array.isArray(property) || typeof property === 'object' } function propertyTypesDoMatch(propA, propB) { if (propA && propB) { return propA.constructor.name === propB.constructor.name } return false } const basics = ['string', 'number', 'boolean', 'bigint', 'undefined', 'symbol', 'function'] function deepEqual(i1, i2) { if (basics.includes(typeof i1) && typeof i1 === typeof i2) { return i1 === i2 } if (Array.isArray(i1) && Array.isArray(i2)) { return i1.every((subItem) => arrayContainsSame(i2, subItem)) } if (typeof i1 === typeof i2 && typeof i1 === 'object') { return Object.entries(i1).every(([key, value]) => { return deepEqual(value, i2[key]) }) } return false } function arrayContainsSame(items, item) { // skippable for loop makes it 1ms faster for (let c = 0; c < items.length; c++) { if (deepEqual(items[c], item)) { return true } } } function mergeArrays(array1, array2) { const all = [...array1] array2.forEach((i) => { if (!arrayContainsSame(all, i)) { all.push(i) } }) return all } function mergeConfigurations(rootConfig, additionalConfig) { let copiedConfig = { ...rootConfig } Object.keys(additionalConfig).forEach((key) => { const doTypesMatch = propertyTypesDoMatch(copiedConfig[key], additionalConfig[key]) const propExistsInRoot = Object.hasOwnProperty.call(copiedConfig, key) if (propExistsInRoot && isMergable(copiedConfig[key]) && doTypesMatch) { if (Array.isArray(copiedConfig[key])) { copiedConfig[key] = mergeArrays(copiedConfig[key], additionalConfig[key]) } else { copiedConfig[key] = mergeConfigurations(copiedConfig[key], additionalConfig[key]) } } else if (propExistsInRoot && doTypesMatch) { copiedConfig[key] = additionalConfig[key] } else { copiedConfig = Object.assign(copiedConfig, { [key]: additionalConfig[key] }) } }) return copiedConfig } var a = { a: 'oh', b: 'my', c: { a: 'a', b: { c: 'c' } } }; var b = { c: { b: { d: 'a' }, c: { d: 'd' } } }; var c = mergeConfigurations(a, b)