Skip to content

Commit e927453

Browse files
committed
perf: replace list length-checks with pattern matching
This replaces few length check on hot paths with patternmatching. According to benchmarks I ran it gives 3-8% or performance gains on parsing a realistic files.
1 parent 47fad18 commit e927453

1 file changed

Lines changed: 13 additions & 8 deletions

File tree

lib/spitfire.ex

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -964,16 +964,21 @@ defmodule Spitfire do
964964
defp invalid_assoc_call_meta?([_entry | meta]), do: invalid_assoc_call_meta?(meta)
965965

966966
defp invalid_assoc_key_in_map?({name, meta, args}) when is_atom(name) and is_list(meta) and is_list(args) do
967-
arity = length(args)
967+
case args do
968+
[_, _ | _] ->
969+
arity = length(args)
968970

969-
arity > 1 and
970-
not Macro.operator?(name, arity) and
971-
not Macro.special_form?(name, arity) and
972-
invalid_assoc_call_meta?(meta)
971+
not Macro.operator?(name, arity) and
972+
not Macro.special_form?(name, arity) and
973+
invalid_assoc_call_meta?(meta)
974+
975+
_ ->
976+
false
977+
end
973978
end
974979

975980
defp invalid_assoc_key_in_map?({{:., _, [_lhs, _rhs]}, meta, args}) when is_list(meta) and is_list(args) do
976-
length(args) > 1 and invalid_assoc_call_meta?(meta)
981+
match?([_, _ | _], args) and invalid_assoc_call_meta?(meta)
977982
end
978983

979984
defp invalid_assoc_key_in_map?({{name, meta, args}, _value}) when is_atom(name) and is_list(meta) and is_list(args) do
@@ -3196,7 +3201,7 @@ defmodule Spitfire do
31963201
{Enum.reverse(pairs), parser}
31973202
end
31983203

3199-
if length(pairs) == 2 do
3204+
if match?([_, _], pairs) do
32003205
tuple = encode_literal(parser, pairs |> List.wrap() |> List.to_tuple(), orig_meta)
32013206
parser = Map.put(parser, :nesting, old_nesting)
32023207
{tuple, parser}
@@ -3418,7 +3423,7 @@ defmodule Spitfire do
34183423

34193424
true ->
34203425
meta =
3421-
if identifier == :op_identifier && length(args) == 1 do
3426+
if identifier == :op_identifier && match?([_], args) do
34223427
[{:ambiguous_op, nil} | meta]
34233428
else
34243429
meta

0 commit comments

Comments
 (0)