<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>
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};
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)
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);
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});
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
object spread | |
object assign | |
immutable-js | |
immutability-helper |
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 |
The benchmark results show that the immutable-js
test is significantly faster than the other tests (immutability-helper
, object assign
, and object spread
).
Here's a breakdown:
immutable-js
: Achieves 1611.97 executions per second, indicating efficient handling of immutability operations within its framework.immutability-helper
: Significantly slower at 237.95 executions per second, suggesting that the helper library's implementation might be less optimized compared to immutable-js
.The remaining tests (object assign
and object spread
) are also slower than immutable-js
, performing at around 100 executions per second. This highlights that built-in JavaScript mechanisms for object manipulation can be comparatively less efficient than dedicated immutability libraries like immutable-js
.
Let me know if you have any more questions or want to explore specific aspects of these benchmarks further!