This question is based on erlang - Which way to compare maps in Elixir - Stack Overflow
Assume a comparison of two huge maps. Erlang documentation explicitly states
Maps are ordered by size, two maps with the same size are compared by keys in ascending term order and then by values in key order. In maps key order integers types are considered less than floats types.
The simple check shows it’s not exactly the case
[m1, m2] = Enum.map([1, 2], fn i -> Map.new(Enum.map(i..1_000_000, &{&1, &1})) end)
Enum.map([true, false], &:timer.tc(fn ->
(&1 or map_size(m1) == map_size(m2)) && :erlang."=:="(m1, m2)
end))
#⇒ [{14941, false}, {20, false}]
# BUT
Enum.map([true, false], &:timer.tc(fn ->
(&1 or map_size(m1) == map_size(m2)) && :erlang."=="(m1, m2)
end))
#⇒ [{35, false}, {33, false}]
Note the enormously huge number in the first case when map_size/1
is not called. The above makes me think that :erlang."=:="/2
does not check sizes upfront.
Unfortunately, I was unable to grep the NIF where the implementation of :erlang."=:="/2
is defined (where otp/erts/preloaded/src/erlang.erl:4176
stub points to.)
So, my question would be: could please anyone more competent in OTP source point me to the implementation and should not we fix Map.equal?/2
in Elixir meanwhile to check for sizes before delegating to :erlang."=:="/2
?
/cc @josevalim