Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
https://stackoverflow.com/posts/61510307 edit
(version: 0)
Benchmark for transforming merged objects
Comparing performance of:
generator vs forloop object assign vs mapReduceSet vs forloopEntries
Created:
6 years ago
by:
Guest
Jump to the latest result
Script Preparation code:
var nrows = 2000, nyears = [...Array(20).keys()].map(x => 2000 + x), nages = [...Array(20).keys()].map(x => `${18+x}`), npeople = [...Array(nrows / nyears.length / nages.length | 0).keys()].map(x => `Person${x}`); var getOneRotate = (x, i) => x[(i / x.length | 0) % x.length]; var data = Array(nrows).fill(0).map((x, i) => ({ year: getOneRotate(nyears,i), name: getOneRotate(npeople,i), age: getOneRotate(nages,i), value: (i / nyears.length | 0) % nyears.length })); const NA='NA'; function forloopObjectAssign(x) { let lname, lage, res=[], years = {}; for ( var i = 0 ; i < x.length ; i++ ) { const {year, value, name, age} = x[i]; if ( lname != name || lage != age ) res.push({name, age}); res[ res.length-1 ][year] = value; years[year] = NA; lname = name; lage = age; } return res.map( x => Object.assign({...years}, x) ); } function forloopEntries(x) { let lname, lage, res=[], years = {}; for ( var i = 0 ; i < x.length ; i++ ) { const {year, value, name, age} = x[i]; if ( lname != name|| lage != age ) res.push([['name',name],['age',age]]); res[ res.length-1 ].push([year,value]); years[year] = NA; lname = name; lage = age; } return res.map( x => Object.fromEntries(Object.entries(years).concat(x)) ); } function mapReduceSet(data) { years = new Set; result = Object .values(data.reduce((r, { name, year, value, ...o }) => { r[name] = r[name] || { name, ...o }; r[name][year] = value; years.add(year); return r; }, {})) .map( (y => o => ({ ...y, ...o })) (Object.fromEntries([...years].map(y => [y, NaN]))) ); return result; } let yearsGenerator = {} function* groupByName(entries) { let group = null; for (const {name, year, value, age} of entries) { if (group === null || group.name !== name || group.age !== age) { if (group !== null) { yield group; } group = {name, age}; } group[year] = value; yearsGenerator[year] = 'NA'; } if (group !== null) { yield group; } } function generator(entries) { return [...groupByName(entries)].map(x=>Object.assign({...yearsGenerator},x)) }
Tests:
generator
generator(data)
forloop object assign
forloopObjectAssign(data)
mapReduceSet
mapReduceSet(data)
forloopEntries
forloopEntries(data)
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (4)
Previous results
Fork
Test case name
Result
generator
forloop object assign
mapReduceSet
forloopEntries
Fastest:
N/A
Slowest:
N/A
Latest run results:
No previous run results
This benchmark does not have any results yet. Be the first one
to run it!
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
I'll do my best to explain what's being tested in this benchmark. **What is being tested?** The benchmark measures the performance of three different JavaScript functions: `forloopObjectAssign`, `mapReduceSet`, and `generator`. These functions are designed to process and transform a large dataset, which represents a merged object with various properties (year, value, name, age). **Options compared** Each function uses a different approach to achieve this transformation: 1. **`forloopObjectAssign`**: This function uses a traditional `for` loop to iterate over the dataset, creating an array of objects by assigning values from the original dataset to new objects. 2. **`mapReduceSet`**: This function uses the built-in `map()` and `reduce()` methods in combination with a Set data structure to process the dataset. It first creates a new object by mapping each entry in the dataset, then reduces it by merging the resulting objects into a single object. 3. **`generator`**: This function uses a generator function (a special type of function that can be used as an iterator) to process the dataset. The generator yields a sequence of values, which are then processed by mapping and reducing. **Pros and cons** Here's a brief summary of each approach: * `forloopObjectAssign`: * Pros: straightforward, easy to understand * Cons: can be slow for large datasets due to the overhead of creating new objects * `mapReduceSet`: * Pros: efficient and scalable, leverages built-in methods for performance gain * Cons: may require more memory due to the use of a Set data structure * `generator`: * Pros: allows for asynchronous processing, can be more memory-efficient than creating arrays * Cons: requires understanding of generator functions and iterators **Library or special JS feature** None of the functions directly utilize a library or a special JavaScript feature beyond the built-in methods mentioned earlier. **Other alternatives** To further optimize performance or improve efficiency: * Using `parallelism` techniques, such as using Web Workers or async/await, could potentially speed up each function by distributing the workload across multiple CPU cores. * Applying techniques like memoization or caching to reduce redundant computations within each function. * Optimizing data structure usage (e.g., switching from an object to a different data structure that's better suited for fast lookups). These are just some ideas, and actual implementation would depend on the specific use case and requirements. Now I hope this answers your questions.
Related benchmarks:
Merge array of objects with an object
Merge array of objects with an object.
Take two arrays and merge them using an object key (Map vs. object)
Array push vs spread concat'''
Merge resources: Object.map
Comments
Confirm delete:
Do you really want to delete benchmark?