DEV Community

Discussion on: Why you should use reduce instead of loops -- Part I

Collapse
 
krzysztofmiemiec profile image
Krzysztof Miemiec

The big performance difference is because you basically compared for in loop with for of. I came up with another performance test set here: jsperf.com/loop-vs-iterator-reduce/5

We have for of loops for reduce and loop tests and "plain-old simple for loops" for simple reduce and simple loop tests. Now we can see that plain-old loops are faster than for of iterators, but at the same time reducer isn't really any slower than regular loop, despite the fact that it's a function call inside a loop. Looks like JS is really good at calling functions 🙃

Collapse
 
babak profile image
Babak

Hi Krzysztof Miemiec, thanks for your feedback, you are correct! I've made the correction to the post. The results are comparable. We can also create a reduce function that utilize better algorithms depending on the data type given. For example

function reduceImproved(
    initialValue,
    reducer,
    data,
  ) {
    let acc = initialValue
    if (data.length) {
      for ( let count = 0, length = data.length; count < length; count++ ) {
        acc = reducer( acc, data[count], count )
      }
    } else {
      let count = 0
      for ( const item of data ) {
        acc = reducer( acc, item, count++ )
      }
    }
    return acc
}

I've not tested this but the idea is that one could create a general purpose reduce for iterators in general while maintaining performance. As mentioned in the article, the reducers themselves can also be improved. We can even reach for WebAssembly, were applicable, and improve our application without having to change a single line of code.

In future parts on this topic, I will go on to discuss how our iterable reduce can be enhanced to handle asynchronous data, such as streams, with ease!

Thanks again for your corrections and feedback!

Collapse
 
krzysztofmiemiec profile image
Krzysztof Miemiec

I think that your utility may end up looking like rxjs 😉 Nevertheless, I get the point that internally optimized, general-purpose reducers can be a cool internal utility for executing loops in a clean & easy-to-read manner. As a performance freak, I'm quite surprised that this approach is that performant. I'll try to use something similar in one of the products I'm working on! Thanks for the article 💪🏻