Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
object assign vs object spread vs immutable-js vs immutability-helper on large data set
(version: 2)
Comparing performance of:
object spread vs object assign vs immutable-js vs immutability-helper
Created:
7 years ago
by:
Registered User
Jump to the latest result
HTML Preparation code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/immutability-helper@2.7.0/index.min.js"></script>
Tests:
object spread
const obj = {}; for(i=0;i<100000;i++){ obj[i] = 'some long string which will need to be copied'; } const obj2 = {key: 'This is final object'} const final = {obj2, ...obj};
object assign
const obj = {}; for(i=0;i<100000;i++){ obj[i] = 'some long string which will need to be copied'; } const obj2 = {key: 'This is final object'} const final = Object.assign({}, obj2, obj)
immutable-js
const obj = {}; for(i=0;i<100000;i++){ obj[i] = 'some long string which will need to be copied'; } const immObj = Immutable.Map(); const obj2 = {key: 'This is final object'} const final = immObj.set(obj2);
immutability-helper
var hasOwnProperty = Object.prototype.hasOwnProperty; var splice = Array.prototype.splice; var toString = Object.prototype.toString var type = function(obj) { return toString.call(obj).slice(8, -1); } var assign = Object.assign || /* istanbul ignore next */ function assign(target, source) { getAllKeys(source).forEach(function(key) { if (hasOwnProperty.call(source, key)) { target[key] = source[key]; } }); return target; }; var getAllKeys = typeof Object.getOwnPropertySymbols === 'function' ? function(obj) { return Object.keys(obj).concat(Object.getOwnPropertySymbols(obj)) } : /* istanbul ignore next */ function(obj) { return Object.keys(obj) }; /* istanbul ignore next */ function copy(object) { if (Array.isArray(object)) { return assign(object.constructor(object.length), object) } else if (type(object) === 'Map') { return new Map(object) } else if (type(object) === 'Set') { return new Set(object) } else if (object && typeof object === 'object') { var prototype = object.constructor && object.constructor.prototype return assign(Object.create(prototype || null), object); } else { return object; } } function newContext() { var commands = assign({}, defaultCommands); update.extend = function(directive, fn) { commands[directive] = fn; }; update.isEquals = function(a, b) { return a === b; }; return update; function update(object, spec) { if (typeof spec === 'function') { return spec(object); } if (!(Array.isArray(object) && Array.isArray(spec))) { } var nextObject = object; var index, key; getAllKeys(spec).forEach(function(key) { if (hasOwnProperty.call(commands, key)) { var objectWasNextObject = object === nextObject; nextObject = commands[key](spec[key], nextObject, spec, object); if (objectWasNextObject && update.isEquals(nextObject, object)) { nextObject = object; } } else { var nextValueForKey = type(object) === 'Map' ? update(object.get(key), spec[key]) : update(object[key], spec[key]); if (!update.isEquals(nextValueForKey, nextObject[key]) || typeof nextValueForKey === 'undefined' && !hasOwnProperty.call(object, key)) { if (nextObject === object) { nextObject = copy(object); } if (type(nextObject) === 'Map') { nextObject.set(key, nextValueForKey); } else { nextObject[key] = nextValueForKey; } } } }) return nextObject; } } var defaultCommands = { $push: function(value, nextObject, spec) { return value.length ? nextObject.concat(value) : nextObject; }, $unshift: function(value, nextObject, spec) { // invariantPushAndUnshift(nextObject, spec, '$unshift'); return value.length ? value.concat(nextObject) : nextObject; }, $splice: function(value, nextObject, spec, originalObject) { // invariantSplices(nextObject, spec); value.forEach(function(args) { // invariantSplice(args); if (nextObject === originalObject && args.length) nextObject = copy(originalObject); splice.apply(nextObject, args); }); return nextObject; }, $set: function(value, nextObject, spec) { // invariantSet(spec); return value; }, $toggle: function(targets, nextObject) { // invariantSpecArray(targets, '$toggle'); var nextObjectCopy = targets.length ? copy(nextObject) : nextObject; targets.forEach(function(target) { nextObjectCopy[target] = !nextObject[target]; }); return nextObjectCopy; }, $unset: function(value, nextObject, spec, originalObject) { // invariantSpecArray(value, '$unset'); value.forEach(function(key) { if (Object.hasOwnProperty.call(nextObject, key)) { if (nextObject === originalObject) nextObject = copy(originalObject); delete nextObject[key]; } }); return nextObject; }, $add: function(value, nextObject, spec, originalObject) { // invariantMapOrSet(nextObject, '$add'); // invariantSpecArray(value, '$add'); if (type(nextObject) === 'Map') { value.forEach(function(pair) { var key = pair[0]; var value = pair[1]; if (nextObject === originalObject && nextObject.get(key) !== value) nextObject = copy(originalObject); nextObject.set(key, value); }); } else { value.forEach(function(value) { if (nextObject === originalObject && !nextObject.has(value)) nextObject = copy(originalObject); nextObject.add(value); }); } return nextObject; }, $remove: function(value, nextObject, spec, originalObject) { // invariantMapOrSet(nextObject, '$remove'); // invariantSpecArray(value, '$remove'); value.forEach(function(key) { if (nextObject === originalObject && nextObject.has(key)) nextObject = copy(originalObject); nextObject.delete(key); }); return nextObject; }, $merge: function(value, nextObject, spec, originalObject) { // invariantMerge(nextObject, value); getAllKeys(value).forEach(function(key) { if (value[key] !== nextObject[key]) { if (nextObject === originalObject) nextObject = copy(originalObject); nextObject[key] = value[key]; } }); return nextObject; }, $apply: function(value, original) { // invariantApply(value); return value(original); } }; var contextForExport = newContext(); const obj = {}; for(i=0;i<100000;i++){ obj[i] = 'some long string which will need to be copied'; } const obj2 = {key: 'This is final object'} const final = contextForExport(obj2, {$merge: obj});
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (4)
Previous results
Fork
Test case name
Result
object spread
object assign
immutable-js
immutability-helper
Fastest:
N/A
Slowest:
N/A
Latest run results:
Run details:
(Test run date:
one year ago
)
User agent:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
Browser/OS:
Chrome 128 on Mac OS X 10.15.7
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
object spread
103.1 Ops/sec
object assign
105.3 Ops/sec
immutable-js
1612.0 Ops/sec
immutability-helper
237.9 Ops/sec
Autogenerated LLM Summary
(model
llama3.1:latest
, generated one year ago):
Based on the provided benchmark results, it appears that: 1. Immutable-js is significantly faster than immutability-helper and object/spread operations. 2. The $merge operation in immutability-helper performs poorly compared to other methods. The main performance differences between the tested scenarios are: * Immutable-js: 1611.97 EPS (Executions Per Second) * Immutability-helper ($merge): 105.31 EPS * Object assign: 103.13 EPS * Object spread: 103.13 EPS It's essential to note that these results might not be applicable in all scenarios, and the performance differences may vary depending on the specific use case.
Related benchmarks:
object assign vs object spread vs immutable-js vs immutability-helper on large data set 2
object assign vs object spread vs immutable-js vs immutability-helper on large data set 3
object assign vs object spread vs immutable-js vs immutability-helper on large data set - z
Spread operator vs Immutable.js performance for common use cases
Comments
Confirm delete:
Do you really want to delete benchmark?