Enum vs. Stream: Use cases in Elixir

Image for post
Image for post

In Elixir there exists two built in modules Enum and Stream. Enum and Stream both give us access to a set of algorithms for working with enumerables. Both also work in linear time (O(n)). In fact, many of the built in functions that can be found in the Enum module, can be found in the Stream module.

Stream and Enum do have their differences however! The biggest difference between the two is the way their algorithms are evaluated. Enum is evaluated eagerly whereas Stream is evaluated lazily. What this means is Stream will wait to evaluate the functions defined using the module until it is explicitly called in someway. Enum on the other hand will immediately process the function call, and store the result in an intermediary list (or other collection depending on the return value of the function being used.)

Image for post
Image for post
Courtesy of: Educative.io

Enum will start by going to each and every element in a collection, applying the transformation to the collection, and then will make a new collection in memory to pass down to the rest of the pipeline.

Image for post
Image for post
Enum’s evaluation of a pipeline

Stream will start by going to the first element, processing the entire pipeline for that entire element, then continues on to the second element.

Image for post
Image for post

Uh oh what happened? Why was nothing inspected like the above code? If the two pipelines are supposed to have identical functionality, why did it not run? Remember, any function used in the Stream module will be lazily evaluated. Since nothing explicitly tells the function to run nor depends on the return statement of the Stream, it does not execute. We can invoke the stream by simply piping it back into an Enum function.

Image for post
Image for post

As you can see, the pipeline evaluates the changes to the first element in the range first, passing it all the way down until it hits the end.

So when should you use which? When dealing with larger, maybe even infinite collections, you should probably stick to using stream. The implications of only having to load the desired elements into memory from the collection to preform operations, as opposed to having to load and preform the desired operation on every single item in the collection, drastically cuts your run times. In some cases it can even be as great as over an %100 increase in performance.

It should be noted however, that Enum preforms better when tasked with operations that need to be done to the entire collection. Loading an entire content of a collection would be done quicker by Enum than Stream. Why is this? Stream has some stuff going on behind the scenes that it needs to run before processing the collection. Because it takes a moment or two to setup, the run time is usually greater than Enum.

TLDR: Use Stream when you are dealing with large collections that you will probably only need a few elements from. Otherwise it is a pretty safe bet to stick to Enum!

Full-Stack Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store