markdev

markdev

Elixir vs. Erlang benchmarks - is one faster than the other?

Is there any significant difference in the runtime speed of programs written in erlang vs. elixir? What (if any) advantages are there to writing one’s source code in raw erlang instead of elixir?

Most Liked

josevalim

josevalim

Creator of Elixir

Yes! Elixir is slightly slower because we dispatch to Enum.reduce and Erlang doesn’t perform a remote call.

We inline most common types with the list type coming first. So for the builtin types, that should be no difference in performance.

@compile {:inline, ...} only works within the same module so it is not a general mechanism for wrapping Erlang functions. The Elixir compiler, however, does inline most of its calls to :erlang.

So there are tiny differences in some very specific cases, but they are quite unlikely to matter in general.

21
Post #4
benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

There are no differences, both compile to the same byte code. Erlang is not more “raw” or low level than Elixir.

15
Post #2
michalmuskala

michalmuskala

Maps have actually two representations depending on the size. Small maps (less than 32 keys) are represented as two sorted arrays - one for keys and one for values. Accessing a key in such a map involves a linear search (and a linear search is much faster than a binary search since the size is so small). Depending on how you look at it, you might say that’s O(n) since it depends on the map size, or O(1) since the worst case is O(32), which is O(1) - the big O notation is not very helpful when talking about small data structures, especially with cache locality and branch prediction effects, you can get significantly different results from what you’d expect by a simple complexity analysis.

Large maps are represented as HAMT and the access is O(log n) - the “forking” factor of the maps is 32, so even very big maps are rather shallow and rarely involve more than 3 levels (32k items).

Anyway, maps are superior to me because of one simple thing - I can read them. Records are terrible in that regard - you get a tagged tuple and you have no idea what the fields mean. Debugging with records is a significantly worse experience and takes much longer. I would reach for records in the tightest loops of the program, where I need some “lolspeed”, but for everything else, maps and structs are plenty fast.

idi527

idi527

Also elixir code might be sometimes less efficient because of the way people write it and not due to the language itself.

  • using string concatenation instead of iolists
  • using structs instead of records
  • accessing map elements via . several times instead of a single pattern match
  • using Keyword.fetch on every element in an “opts” list instead of iterating over it once
  • in general, trying to use elixir “imperatively” thus producing subpar code (many examples of this on this very forum)
12
Post #5
benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Sure, let me make this a bit more concrete.

When you write literally the same code, you get literally the same bytecode. Examples:

 -module(math).
 -export([factorial/1]).

 factorial(0) ->
   1;
 factorial(X) when X > 0 ->
   X * factorial(X-1).

Will produce exactly the same bytecode as

defmodule Factorial do
  def factorial(0), do: 1
  def factorial(x) when x > 0, do: x * factorial(x - 1)
end

Literally 100% the same. Now, the Elixir standard library sometimes favors certain patterns of abstractions that provide a negligible, but not technically 0 cost compared to an erlang alternative. So for example:

Enum.map(list, fn x -> x * 2 end)

has 1 function call more over head (1 period, not 1 per item) than:

lists:map(fun(X) -> 2*X end, List).

because the Enum.map function will convert non list things to a list in order to map over them. If it is a list, it will just call that same function, which you can do yourself:

# this is elixir code
:lists.map(fn x -> x * 2 end, items)

and that ^ is again byte for byte identical with the erlang code.

So in terms of which one is faster, what it really boils down to is the approaches that each library takes. Certain things that Elixir macros let you do for example make certain high performance strategies a lot easier or more ergonomic than in erlang, and so it can actually be faster. Other times the desire to create friendly APIs in Elixir can sometimes introduce slightly more indirection, which can introduce small if technically non zero overhead.

Fundamentally though whether your Elixir code has overhead WRT erlang is entirely a question of what Elixir code you write. They compile to time same core structure, and end up as the same bytes.

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement