Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
ETST 123123123123123
(version: 1)
Lodash uniqBy vs [...new Set()]
Comparing performance of:
uniqBy vs Set with filter
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> function stringifiable(obj) { // Safely stringify Object.create(null) /* istanbul ignore next */ return typeof obj === 'object' && !('toString' in obj) ? Object.prototype.toString.call(obj).slice(8, -1) : obj; } var isProduction = typeof process === 'object' && process.env.NODE_ENV === 'production'; function invariant(condition, message) { if (!condition) { /* istanbul ignore next */ if (isProduction) { throw new Error('Invariant failed'); } throw new Error(message()); } } var hasOwnProperty = Object.prototype.hasOwnProperty; var splice = Array.prototype.splice; var toString = Object.prototype.toString; function type(obj) { return toString.call(obj).slice(8, -1); } var assign = Object.assign || /* istanbul ignore next */ (function (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); }; function copy(object) { return Array.isArray(object) ? assign(object.constructor(object.length), object) : (type(object) === 'Map') ? new Map(object) : (type(object) === 'Set') ? new Set(object) : (object && typeof object === 'object') ? assign(Object.create(Object.getPrototypeOf(object)), object) /* istanbul ignore next */ : object; } var Context = /** @class */ (function () { function Context() { this.commands = assign({}, defaultCommands); this.update = this.update.bind(this); // Deprecated: update.extend, update.isEquals and update.newContext this.update.extend = this.extend = this.extend.bind(this); this.update.isEquals = function (x, y) { return x === y; }; this.update.newContext = function () { return new Context().update; }; } Object.defineProperty(Context.prototype, "isEquals", { get: function () { return this.update.isEquals; }, set: function (value) { this.update.isEquals = value; }, enumerable: true, configurable: true }); Context.prototype.extend = function (directive, fn) { this.commands[directive] = fn; }; Context.prototype.update = function (object, $spec) { var _this = this; var spec = (typeof $spec === 'function') ? { $apply: $spec } : $spec; if (!(Array.isArray(object) && Array.isArray(spec))) { invariant(!Array.isArray(spec), function () { return "update(): You provided an invalid spec to update(). The spec may " + "not contain an array except as the value of $set, $push, $unshift, " + "$splice or any custom command allowing an array value."; }); } invariant(typeof spec === 'object' && spec !== null, function () { return "update(): You provided an invalid spec to update(). The spec and " + "every included key path must be plain objects containing one of the " + ("following commands: " + Object.keys(_this.commands).join(', ') + "."); }); var nextObject = object; getAllKeys(spec).forEach(function (key) { if (hasOwnProperty.call(_this.commands, key)) { var objectWasNextObject = object === nextObject; nextObject = _this.commands[key](spec[key], nextObject, spec, object); if (objectWasNextObject && _this.isEquals(nextObject, object)) { nextObject = object; } } else { var nextValueForKey = type(object) === 'Map' ? _this.update(object.get(key), spec[key]) : _this.update(object[key], spec[key]); var nextObjectValue = type(nextObject) === 'Map' ? nextObject.get(key) : nextObject[key]; if (!_this.isEquals(nextValueForKey, nextObjectValue) || 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; }; return Context; }()); var defaultCommands = { $push: function (value, nextObject, spec) { invariantPushAndUnshift(nextObject, spec, '$push'); 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 (values, nextObject, _spec, originalObject) { invariantMapOrSet(nextObject, '$add'); invariantSpecArray(values, '$add'); if (type(nextObject) === 'Map') { values.forEach(function (_a) { var key = _a[0], value = _a[1]; if (nextObject === originalObject && nextObject.get(key) !== value) { nextObject = copy(originalObject); } nextObject.set(key, value); }); } else { values.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 defaultContext = new Context(); var update = defaultContext.update; // invariants function invariantPushAndUnshift(value, spec, command) { invariant(Array.isArray(value), function () { return "update(): expected target of " + stringifiable(command) + " to be an array; got " + stringifiable(value) + "."; }); invariantSpecArray(spec[command], command); } function invariantSpecArray(spec, command) { invariant(Array.isArray(spec), function () { return "update(): expected spec of " + stringifiable(command) + " to be an array; got " + stringifiable(spec) + ". " + "Did you forget to wrap your parameter in an array?"; }); } function invariantSplices(value, spec) { invariant(Array.isArray(value), function () { return "Expected $splice target to be an array; got " + stringifiable(value); }); invariantSplice(spec.$splice); } function invariantSplice(value) { invariant(Array.isArray(value), function () { return "update(): expected spec of $splice to be an array of arrays; got " + stringifiable(value) + ". " + "Did you forget to wrap your parameters in an array?"; }); } function invariantApply(fn) { invariant(typeof fn === 'function', function () { return "update(): expected spec of $apply to be a function; got " + stringifiable(fn) + "."; }); } function invariantSet(spec) { invariant(Object.keys(spec).length === 1, function () { return "Cannot have more than one key in an object with $set"; }); } function invariantMerge(target, specValue) { invariant(specValue && typeof specValue === 'object', function () { return "update(): $merge expects a spec of type 'object'; got " + stringifiable(specValue); }); invariant(target && typeof target === 'object', function () { return "update(): $merge expects a target of type 'object'; got " + stringifiable(target); }); } function invariantMapOrSet(target, command) { var typeOfTarget = type(target); invariant(typeOfTarget === 'Map' || typeOfTarget === 'Set', function () { return "update(): " + stringifiable(command) + " expects a target of type Set or Map; got " + stringifiable(typeOfTarget); }); } </script>
Script Preparation code:
var myArr = Array.from({ length: 1_000_000 }, () => ({ id: Math.floor(Math.random() * 1000) })); var myArr2 = Array.from({ length: 1_000_000 }, () => ({ id: Math.floor(Math.random() * 1000) })); var myCopy = null;
Tests:
uniqBy
myCopy = _.uniqBy([...myArr, ...myArr2], 'id');
Set with filter
myCopy = (() => { const existingIds = new Set(myArr.map((machine) => machine.id)); const newMachines = myArr2.filter((machine) => !existingIds.has(machine.id)); return update(myArr, { $push: newMachines, }); })();
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (2)
Previous results
Fork
Test case name
Result
uniqBy
Set with filter
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/133.0.0.0 Safari/537.36
Browser/OS:
Chrome 133 on Mac OS X 10.15.7
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
uniqBy
25.7 Ops/sec
Set with filter
16.0 Ops/sec
Related benchmarks:
lodash forEach vs ramda forEach vs array.forEach vs for loop
Js Unique
Lodash uniqBy vs Set
Lodash uniqBy vs Set 10000
Lodash uniqBy vs Set with Array of object
uniq vs uniqBy vs Set
Lodash Uniq vs Javascript Set vs Ramda Strings
lodash uniq vs set my 2
New set vs UniqWith
Comments
Confirm delete:
Do you really want to delete benchmark?