给定两个不同的大地图,定义如下
Interactive Elixir (1.9.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> m1 = Map.new(1..1_000_000 |> Enum.map(&{&1, &1})); :ok
:ok
iex(2)> m2 = Map.new(2..1_000_000 |> Enum.map(&{&1, &1})); :ok
:ok
Run Code Online (Sandbox Code Playgroud)
使用==/2和比较它们时需要显着的时间差异Map.equal?/2
iex(3)> :timer.tc(fn -> m1 == m2 end)
{21, false}
iex(4)> :timer.tc(fn -> Map.equal?(m1, m2) end)
{20487, false}
Run Code Online (Sandbox Code Playgroud)
==/2和之间的时间差异是什么原因,Map.equal?/2使用哪个?
同样,在==/2和之间使用哪个===/2?(因为Map.equal?/2调用===/2,请参见此处)
谢谢
事实上,Map.equal?/2只是委托给Kernel.===/2。
Kernel.===/2正在委托给:erlang."=:="/2并且Kernel.==/2正在委托给:erlang."=="/2。后者比较数字,而前者比较值和类型。
考虑以下示例。
%{1 => 1} == %{1 => 1.0}
#? true
%{1 => 1} === %{1 => 1.0}
#? false
Run Code Online (Sandbox Code Playgroud)
也就是说,Kernel.===/2应该比较所有值。OTOH,二郎山/ OTP参考明确指出的是
映射按大小排序,大小相同的两个映射按关键字升序进行比较,然后按关键字顺序按值进行比较。在地图中,键顺序整数类型被认为小于浮点类型。
如果确实如此,则如您的示例中所示,大小不同的两张地图应该几乎同时返回。
综上所述,我认为这个时间差是实现中的一个错误:erlang."=:="/2,值得向Erlang团队报告。