diff options
author | Eric Meadows-Jönsson <eric.meadows.jonsson@gmail.com> | 2020-07-08 13:15:40 +0200 |
---|---|---|
committer | Eric Meadows-Jönsson <eric.meadows.jonsson@gmail.com> | 2020-07-08 13:15:40 +0200 |
commit | 2011919b633d158ca3e369431662e44391e09a2a (patch) | |
tree | b58710adbf4da40020ea1df4ff9db1f52107caa9 | |
parent | 85968b60098bc84599c2668f81e1f72d85b9b5af (diff) | |
download | elixir-emj/optimize-unification.tar.gz |
Optimize variable unificationemj/optimize-unification
Avoids building large chains of variable references by always resolving
to the last variable.
Instead of building a chain of references:
var1 -> var2 -> ... -> varN -> type()
We now create a direction reference:
var1 -> varN -> type()
This change vastly improves the speed of checking functions with high
complexity and many variables.
-rw-r--r-- | lib/elixir/lib/module/types/infer.ex | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/elixir/lib/module/types/infer.ex b/lib/elixir/lib/module/types/infer.ex index 0a3bf7995..a84c297bb 100644 --- a/lib/elixir/lib/module/types/infer.ex +++ b/lib/elixir/lib/module/types/infer.ex @@ -32,11 +32,23 @@ defmodule Module.Types.Infer do end defp do_unify(type, {:var, var}, stack, context) do - unify_var(var, type, stack, context, _var_source = false) + case Map.fetch!(context.types, var) do + {:var, var_type} -> + do_unify(type, {:var, var_type}, stack, context) + + _other -> + unify_var(var, type, stack, context, _var_source = false) + end end defp do_unify({:var, var}, type, stack, context) do - unify_var(var, type, stack, context, _var_source = true) + case Map.fetch!(context.types, var) do + {:var, var_type} -> + do_unify({:var, var_type}, type, stack, context) + + _other -> + unify_var(var, type, stack, context, _var_source = true) + end end defp do_unify({:tuple, sources}, {:tuple, targets}, stack, context) |