<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
const max2 = 500000;
var rows = [];
for (let i = 0; i <= max2; i++) { // Use `let` for `i` as it’s updated in each loop iteration
rows.push({
id: i,
task_id: i % 1000,
name: `Task ${i}`,
status: i % 2 === 0 ? 'active' : 'inactive',
description: `Description for task ${i}`,
priority: Math.floor(Math.random() * 5) + 1
});
}
const lodashMapValuesOmitGrouped = _.mapValues(_.groupBy(rows, 'task_id'), group =>
group.map(row => _.omit(row, 'task_id'))
);
const nativeReduceGrouped = rows.reduce((acc, row) => {
const { task_id, rest } = row; // Exclude `task_id` using destructuring
if (!acc[task_id]) acc[task_id] = []; // Initialize array for this `task_id`
acc[task_id].push(rest); // Add the item without `task_id` to the group
return acc;
}, {});
const customReduceGrouped = rows.reduce((acc, row) => {
if (!acc[row.id]) acc[row.id] = []; // Initialize an array for each unique id
const rowData = Object.keys(row).reduce((obj, key) => {
if (key !== 'id') obj[key] = row[key]; // Exclude 'id' to avoid nesting
return obj;
}, {});
acc[row.id].push(rowData);
return acc;
}, {});
const lodashGroupedWithDelete = _.groupBy(rows, 'task_id');
Object.values(lodashGroupedWithDelete).forEach(group => {
group.forEach(item => {
delete item.task_id; // Remove `task_id` directly from each item
});
});
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
Lodash with _.mapValues and _.omit | |
Native reduce Grouping with Destructuring | |
Custom reduce with Object.keys Filtering | |
Lodash Grouping with Native Key Removal |
Test name | Executions per second |
---|---|
Lodash with _.mapValues and _.omit | 2.8 Ops/sec |
Native reduce Grouping with Destructuring | 14.5 Ops/sec |
Custom reduce with Object.keys Filtering | 8.4 Ops/sec |
Lodash Grouping with Native Key Removal | 44.2 Ops/sec |
The benchmark at MeasureThat.net compares different JavaScript methods for grouping an array of objects based on a specific property (task_id
). The benchmark tests four different approaches to achieve this:
Lodash with _.mapValues
and _.omit
:
rows
array into an object based on task_id
using _.groupBy
, and then applies _.mapValues
to omit the task_id
from each grouped item.Native reduce
Grouping with Destructuring:
Array.prototype.reduce
function along with destructuring to group the items. The task_id
is excluded directly in the destructuring assignment for each row.Custom reduce
with Object.keys
Filtering:
reduce
, iterating through the keys of each object. It manually filters out the id
key for each object in the grouping process.Lodash Grouping with Native Key Removal:
_.groupBy
from Lodash to create groups and then iterates through each group to delete task_id
directly from each object using the delete
operator.delete
, providing a straightforward way to remove keys.delete
can be slow, as it alters the structure of each object and may result in performance penalties, especially in tight loops or large datasets.Based on the benchmark results executed on a specific browser, we see the following performances (measured in executions per second):
reduce
Grouping with Destructuring: 16.82 executions/secreduce
with Object.keys
Filtering: 8.79 executions/sec_.mapValues
and _.omit
: 3.15 executions/sec (slowest)reduce
and map
, which have the combined benefit of being part of the standard language with no external dependencies. There are also other utility libraries, such as Ramda, that offer similar functionality with functional programming paradigms.In conclusion, this benchmark provides valuable insights into the trade-offs between using a dedicated library and using native JavaScript methods under different scenarios involving data manipulation and object grouping.