Efficiency of IO lists in elixir/erlang

The idea is that when you concatenate the two lists a and b: result = a ++ b, this takes O(length(a)+1) steps, because only after traversing all of list A you know how to combine them. This linear amount of time is spent évery time we want to concatenate two strings. Usually it is common to add new parts of strings to the end of the already-existing string, meaning that the length of a will quickly grow.

But if you concatenate IOLists by doing result = [a, b], then this only takes O(2) steps to compute, since only the pointers to the heads of these lists (which the BEAM already has available; this is the only piece of data that is kept for a linked list) need to be read and copied over to a new list.

Yes, when consuming (‘flattening’) an IOList, it will take a little more steps to follow all the nested list-of-list cases to end up with a single linear sequence again, but this only needs to happen ónce, namely when you’re done with building the IOList.

And that’s why using IOLists is faster in many common cases.

(Using binaries instead of charlists moves this problem from normale lists consuming more time than IOLists to concatenated binaries consuming more memory and needing more copying than IOLists where only the pointers to the already-existing data need to be copied, but the example still holds.)

7 Likes