Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
reduce: spreading acc vs mutating acc
(version: 1)
Comparing performance of:
spread acc vs mutate acc
Created:
one year ago
by:
Guest
Jump to the latest result
HTML Preparation code:
<!--your preparation HTML code goes here-->
Script Preparation code:
function generateID(length = 10) { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; const charactersLength = characters.length; for (let i = 0; i < length; i++) { // Generate a random index based on characters length const randomIndex = Math.floor(Math.random() * charactersLength); // Append the character at the random index to the result string result += characters[randomIndex]; } return result; } const data = new Array(100).fill('a').map(() => ({ key: generateID(), value: 'value' }));
Tests:
spread acc
const result = data.reduce((acc, item) => { return { ...acc, [item.key]: item.value, }; }, {});
mutate acc
const result = data.reduce((acc, item) => { acc[item.key] = item.value; return acc; }, {});
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (2)
Previous results
Fork
Test case name
Result
spread acc
mutate acc
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/131.0.0.0 Safari/537.36
Browser/OS:
Chrome 131 on Mac OS X 10.15.7
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
spread acc
5378.3 Ops/sec
mutate acc
165151.7 Ops/sec
Autogenerated LLM Summary
(model
gpt-4o-mini
, generated one year ago):
This benchmark tests two approaches to accumulating data using the `Array.prototype.reduce` method in JavaScript: one that uses the "spread" syntax to create a new object on each iteration and another that mutates the accumulator object directly. ### Approaches Tested: 1. **Spread Accumulator (`spread acc`)**: ```javascript const result = data.reduce((acc, item) => { return { ...acc, [item.key]: item.value, }; }, {}); ``` - **Description**: In this approach, on each iteration of the `reduce`, a new object is created by spreading the contents of the accumulator (`acc`) into a new object and adding a new key-value pair from the current `item`. - **Pros**: - Immutable Pattern: Keeps the original accumulator untouched, which can be beneficial in functional programming paradigms where immutability is favored. - Clearer intention: Might be easier to understand at a glance since it resembles merging two objects. - **Cons**: - Performance: Creates a new object on every iteration, leading to significantly higher memory and CPU usage, especially with larger datasets. 2. **Mutating Accumulator (`mutate acc`)**: ```javascript const result = data.reduce((acc, item) => { acc[item.key] = item.value; return acc; }, {}); ``` - **Description**: This approach modifies the `acc` object directly by assigning the new key-value pairs from the `item`. - **Pros**: - Performance: More efficient since it avoids the overhead of creating new objects. This is particularly advantageous in high-performance scenarios. - Lower memory footprint: Reduces the amount of temporary objects created during the execution of the function. - **Cons**: - Mutable Pattern: Alters the accumulator directly, which can lead to bugs in environments where immutability is important (e.g., React state management). - Less clear intent: It may be slightly harder to follow what is happening, especially for new developers or those less familiar with JavaScript. ### Benchmark Results: - **Mutate Acc**: Achieved **206025.27 executions per second**. - **Spread Acc**: Only managed **5350.79 executions per second**. ### Conclusion and Considerations: The benchmark clearly indicates that mutating the accumulator is significantly faster than using the spread operator for creating new objects in this scenario. ### Alternatives: Beyond these two options, there are additional alternatives for accumulating data: - **Using `Object.assign()`**: Similar to the spread method but slightly more efficient than the spread operator, particularly in some engines. ```javascript const result = data.reduce((acc, item) => { return Object.assign({}, acc, { [item.key]: item.value }); }, {}); ``` - **Using a `for` loop**: If performance is a critical requirement, using a simple `for` loop may offer even better performance due to reduced overhead in function calls and operations. ```javascript const result = {}; for (let i = 0; i < data.length; i++) { result[data[i].key] = data[i].value; } ``` Each alternative has its trade-offs in terms of readability, maintainability, and performance, depending on the specific use case and the developers' preferences.
Related benchmarks:
Lodash _.some vs _.includes
Lodash _.some vs _.includes vs array.find
Lodash vs vanila 2
get with insert : Array vs Map 3
toLowerCase() Sorting
IndexOf vs Includes vs lodash includes vs dictionary with large array
Split vs Spread (randomized)
lodash _.some vs Array.some
.concat() is slow (immutable) vs .push() (mutation)
Comments
Confirm delete:
Do you really want to delete benchmark?