Perhaps it should be. We have discussed adding notes about the complexity for common functions.
A rule of thumb for naming in Erlang/OTP is that functions having size
in their name are O(1), while functions having length
in their name are O(N)
.
Yes, that is more direct way to test whether a map is empty. In Erlang/OTP 27, that happens to result in slightly smaller native code than map_size(Map) == 0
. That is one of the miscellaneous optimizations that I happened to mention in my blog post. In Erlang/OTP 26 and earlier, Map == #{}
would not be inlined by the JIT and thus be somewhat slower than map_size(Map) == 0
.
Digging deeper, let’s look at the native code.
For map_size(Map) == 0
in a guard, the JIT in both Erlang/OTP 26 and Erlang/OTP 27 generates the following native code:
# bif_map_size_jsd
mov rax, qword ptr [rbx]
test al, 1
jne label_3
mov ecx, dword ptr [rax-2]
and cl, 63
cmp cl, 44
jne label_3
L17:
L18:
mov rax, qword ptr [rax+6]
shl rax, 4
or al, 15
mov qword ptr [rbx], rax
# is_eq_exact_fss
# simplified check since one argument is an immediate
# simplified compare of BEAM register
cmp rax, 15
jne label_3
That is, the JIT inlines both the call to map_size/1
and the call to =:=
(the Erlang compiler has replaced ==
with =:=
because the latter is more efficient while giving the same result in this case).
For Map == #{}
, the JIT in Erlang/OTP 26 generates the following code:
# is_eq_exact_fss
L22:
long mov rsi, 9223372036854775807
mov rdi, qword ptr [rbx]
cmp rdi, rsi
short je L21
rex test dil, 1
jne label_6
mov rbp, rsp
lea rsp, qword ptr [rbx-128]
vzeroupper
call 94546710368096
mov rsp, rbp
test eax, eax
je label_6
L21:
Here the JIT generates code to call the general function for testing two Erlang terms for exact equality.
In Erlang/OTP 27, the JIT generates the following code:
# is_eq_exact_fss
# optimized equality test with empty map
mov rdi, qword ptr [rbx]
rex test dil, 1
short jne label_3
cmp dword ptr [rdi-2], 300
short jne label_3
cmp dword ptr [rdi+6], 0
short jne label_3
# i_move_sd
That is, the comparison has been inlined.