Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Lodash cloneDeep vs structuredClone 2222
(version: 1)
https://developer.mozilla.org/en-US/docs/Web/API/structuredClone
Comparing performance of:
Lodash cloneDeep vs Native structuredClone vs DeepCopy
Created:
one year ago
by:
Guest
Jump to the latest result
HTML Preparation code:
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js'></script>
Script Preparation code:
var MyObject2 = { description: 'Creates a deep copy of source, which should be an object or an array.', myNumber: 123456789, myBoolean: true, jayson: { stringify: 'JSON.stringify() method converts a JavaScript value to a JSON string....', parse: 'JSON.parse() method parses a JSON string...' } }; var MyObject = { "userId": "134374683951759360", "guild": "86908735326281728", "status": "online", "activities": [{ "name": "Twitch", "type": 1, "url": "https://www.twitch.tv/craggle25", "details": "Weekend dirt naps with @mart0k and Cat. Hunt Showdown", "state": "Hunt: Showdown", "applicationId": null, "timestamps": null, "party": null, "assets": { "largeText": null, "smallText": null, "largeImage": "twitch:craggle25", "smallImage": null }, "flags": 0, "emoji": null, "buttons": [], "createdTimestamp": 1697880668811 }], "clientStatus": { "desktop": "online" } }; var myCopy = null; function deepCopy(data) { let node; if (Array.isArray(data)) { node = data.length > 0 ? data.slice(0) : []; node.forEach((e, i) => { if (typeof e === 'object' || (Array.isArray(e) && e.length > 0)) { node[i] = deepCopy(e); } }); } else if (data && typeof data === 'object') { node = data instanceof Date ? data : Object.assign({}, data); Object.keys(node).forEach(key => { if (typeof node[key] === 'object' || (Array.isArray(node[key]) && node[key].length > 0)) { node[key] = deepCopy(node[key]); } }); } else { node = data; } return node; // structuredClone(data) } function isArr(x) { return Array.isArray(x); } function isObject(x) { return typeof x === 'object'; } function shallowClone(obj) { let clone = {}; for (let key in obj) { let r = obj[key]; let isArray = isArr(r); if (!isArray && isObject(r)) { continue; } if (isArray) { clone[key] = []; for (let i = 0; i < r.length; i++) { clone[key][i] = shallowClone(r[i]); } } else { clone[key] = r; } } return clone; } // pulled this from https://github.com/nodejs/node/issues/34355#issuecomment-658394617 function deepClone(o) { if (typeof o !== "object") { return o } if (!o) { return o } // https://jsperf.com/deep-copy-vs-json-stringify-json-parse/25 if (Array.isArray(o)) { const newO = [] for (let i = 0; i < o.length; i += 1) { const val = !o[i] || typeof o[i] !== "object" ? o[i] : deepClone(o[i]) newO[i] = val === undefined ? null : val } return newO } const newO = {} for (const i of Object.keys(o)) { const val = !o[i] || typeof o[i] !== "object" ? o[i] : deepClone(o[i]) if (val === undefined) { continue } newO[i] = val } return newO } let iterations = [100, 10000, 1000000, 10000000]; function profile(name, func) { for (let iterationCount of iterations) { let n = name + " at " + iterationCount + " iterations"; console.time(n); for (let i = 0; i < iterationCount; i++) { func(); } console.timeEnd(n); } console.log(""); } profile('StructuredClone', () => { structuredClone(MyObject); }); profile('ParseStringify', () => { JSON.parse(JSON.stringify(MyObject)) }); profile('ShallowClone', () => { shallowClone(MyObject); }); profile('DeepClone', () => { deepClone(MyObject); }); profile('DeepCopy', () => { deepCopy(MyObject); }); profile('lodash', () => { _.cloneDeep(MyObject); });
Tests:
Lodash cloneDeep
myCopy = _.cloneDeep(MyObject);
Native structuredClone
myCopy = structuredClone(MyObject);
DeepCopy
myCopy = deepCopy(MyObject);
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (3)
Previous results
Fork
Test case name
Result
Lodash cloneDeep
Native structuredClone
DeepCopy
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/135.0.0.0 Safari/537.36
Browser/OS:
Chrome 135 on Windows
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
Lodash cloneDeep
249228.8 Ops/sec
Native structuredClone
179351.8 Ops/sec
DeepCopy
749346.0 Ops/sec
Autogenerated LLM Summary
(model
gpt-4o-mini
, generated one year ago):
The benchmark under consideration compares the performance of several methods for creating deep copies of JavaScript objects. It includes tests of `lodash`'s `cloneDeep` method, the native `structuredClone` function introduced in modern JavaScript, and a custom recursive deep copy function. Here's a breakdown of each method being tested, their pros and cons, and additional considerations. ### Methods Compared 1. **Lodash's `cloneDeep`** - **Pros**: - A widely used and battle-tested utility function. - Handles various edge cases, including deep cloning of functions, dates, special objects, and circular references. - **Cons**: - It adds a dependency on the Lodash library, which may increase the size of the application. - Generally slower than native solutions due to its comprehensive checks and balances. 2. **Native `structuredClone`** - **Pros**: - This is a built-in method in modern browsers, which minimizes the need for external libraries. - It can clone a wider variety of types, including `Map`, `Set`, `ArrayBuffer`, `Date`, and handles circular references automatically. - **Cons**: - It is not yet available in all JavaScript environments (e.g., older browsers like Internet Explorer). - If usage must remain compatible with older environments, polyfills or fallbacks may be necessary. 3. **Custom `deepCopy` Function** - **Pros**: - No external dependencies, fully customizable. - Can be optimized for specific data structures if you know the dataset is homogenous. - **Cons**: - It may not handle all edge cases (e.g., circular references, or different types of objects like `Date`), depending on implementation. - More prone to bugs if modifications are made or if the code doesn't account for all scenarios. ### Other Alternatives - **JSON Serialization (using `JSON.stringify` and `JSON.parse`)**: - **Pros**: Simple and easy to implement. - **Cons**: Doesn't handle functions or special object types well and loses more complex structures like `Date`. Also, it can introduce performance bottlenecks due to serialization/deserialization overhead. - **Shallow Copy (Using a method like `Object.assign` or spread operator)**: - While not directly tested here, shallow copies can be an option if only a shallow clone is sufficient for the data being manipulated. ### Summary of Benchmark Testing The benchmark's results reflect the execution speed of each method under varying iterations. The `DeepCopy` function outperformed the others significantly in terms of executions per second, followed by `Lodash's cloneDeep`. The `structuredClone` function, while native and versatile, was the slowest among the methods tested. In conclusion, the choice of deep copy method should depend on specific project requirements. If performance is critical, a custom solution that suits your data's needs may be best. However, for comprehensive support across various JavaScript object types, `structuredClone` or `lodash` should be considered, keeping in mind the implications of dependencies and browser compatibility.
Related benchmarks:
Lodash cloneDeep vs structuredClone vs JSON Parse
Lodash cloneDeep vs structuredClone vs JSON clone
Lodash cloneDeep vs JSON.parse
Lodash cloneDeep vs structuredClone vs JSON
Lodash cloneDeep vs structuredClone vs naive JSON.stringify
Lodash cloneDeep vs structuredClone vs JSON-Clone
Lodash cloneDeep vs json.parse+stringify
Lodash cloneDeep vs structuredClone vs JSON encoding
Lodash cloneDeep vs structuredClone 22222
Comments
Confirm delete:
Do you really want to delete benchmark?