Skip to content

Performance

Brian Underwood edited this page Apr 7, 2025 · 1 revision

Performance may sometimes be a valid reason for using Enum.reduce. But you should consider two issues:

  • Is there a noticeable enough performance boost to be noticed, given the use-cases which are normally processed?
  • Is the performance benefit noticeable enough to warrant affecting readability?

To understand use-cases better this repo has some benchmarks under the benchmarks directory.

The results of the benchmarks are below.

Important

The benchmarks are run with benchee and the results are shown based off of the "iterations per second", which is just the inverse of how fast each algorithm ran. Because it is hard to show the scale changes in a chart as the size of the inputs is ramped up, the charts are normalized as a percentage of the fastest test for each input size. So it's very important to remember that while one algorithm might be faster for a size of 10, 100, or 1000 elements, the amount of time spent is often practically the same between the different algorithms.

You can check out the code for more details, but to summarize:

Algorithms are run on integers (starting with a range of 1..n) and maps (a list of maps of size n)

  • map - Transform every integer/map
  • filter - Reduce the number of elements by half
  • filter+map - Combination of the above
  • any? - Calling Enum.any? which will return true half-way through
  • filter+map+any? - Combination of the three steps above

If you'd like to run these benchmarks yourself you can run mix run benchmarks/benchmark.exs and, if you want to see charts, you can use the benchmarks/run.livemd LiveBook file.

algorithm: map

visualization visualization-2

The integers shows reduce / map as the best options and then gradually switching with stream being a better option

The maps situation is less clear, with a lot of switching back and forth. This is probably due to memory / garbage collection of the larger amount of data being worked with.

algorithm: any?

visualization-3 visualization-4

Here the story seems clear that Enum.any? holds up quite well for all input sizes. The reduce_while implementation is often better for maps, but not significantly.

algorithm: filter + map

visualization-5 visualization-6

Here we see that when we need to start piping operations, using the Stream module is a strong choice. But still the difference isn't big until you start getting to larger inputs of integers.

algorithm: filter + map + any?

visualization-7 visualization-8

Here we find the clearest distinctions of all. When doing a pipeline of operations which end in a reduction to a value, reduce_while is the fastest with the Stream module providing a decent alternative which is still readable.

Clone this wiki locally