In a case you have to create a Map
with 15 ~ 20 fields, who is more performatic? A hardcoded map
%{foo: 1, bar: 2, baz: 3 ...}
Or builda Map using Map.put
%{}
|> Map.put(:foo, 1)
|> Map.put(:bar, 2)
...
In a case you have to create a Map
with 15 ~ 20 fields, who is more performatic? A hardcoded map
%{foo: 1, bar: 2, baz: 3 ...}
Or builda Map using Map.put
%{}
|> Map.put(:foo, 1)
|> Map.put(:bar, 2)
...
First one.
you could test using benchee | Hex - most likely hardcoded, for obvious reasons…
Depends on the exact details of the keys and values, but there’s less difference between the two than you’d think if things are compile-time constants.
Here’s a module to demonstrate that:
defmodule Bar do
@compile :S
def bar do
%{}
|> Map.put(:a, 1)
|> Map.put(:b, 2)
end
def baz do
%{a: 1, b: 2}
end
def huh(a, b) do
%{a: a, b: b}
end
def wat(a, b) do
%{}
|> Map.put(:a, a)
|> Map.put(:b, b)
end
end
The @compile :S
attribute causes the compiler to emit a BEAM assembly file with a .S
extension and then crash. That file is a human-readable version of what the compiler converts to a .beam
artifact. Check out the BEAM Book for details on exactly what’s happening, but you don’t need to be fluent in the VM bytecode to draw conclusions.
First observation: baz
’s implementation is a single move from the literal pool. Since the Map
is immutable, every call to baz
can return a reference to the same structure.
Second observation: bar
’s implementation is… ALSO a single move from the literal pool. The compiler has noticed that the expression in bar
returns a constant value and pre-calculated it at compile-time. So the answer to your original specific question is “there’s absolutely no difference”, since the two forms compile to exactly the same assembly.
Third observation: the implementation in huh
uses a single put_map_assoc
instruction that combines the literal keys and the input arguments.
Final observation: the implementation in wat
is optimized to match huh
exactly! Again, the compiler has observed that the result can be pre-computed.
You can experiment with the limits of this optimization; for instance, adding a Map.put
to wat
s chain with a non-constant key will force two put_map_assoc
calls to be used.