gpt4 book ai didi

erlang - 为什么模式匹配性能并不比 elixir 中的 ifelse/cond 好多少?

转载 作者:行者123 更新时间:2023-12-03 18:12:53 26 4
gpt4 key购买 nike

有人告诉我 erlang 光束通过模式匹配进行了很多调整,因此性能比条件表达式要好得多。我在 elixir 中做了一个测试,并用 benchfella 运行了基准测试。但是,我发现与 if/cond 相比,模式匹配性能几乎是相同的性能水平。

$ mix bench -d 10
Settings:
duration: 10.0 s
mem stats: false
sys mem stats: false

[12:30:08] 1/3: PatternMatchBench.if else performance
[12:30:28] 2/3: PatternMatchBench.cond performance
[12:30:47] 3/3: PatternMatchBench.pattern match performance
Finished in 57.5 seconds

PatternMatchBench.if else performance: 10000 1723.24 µs/op
PatternMatchBench.cond performance: 10000 1723.36 µs/op
PatternMatchBench.pattern match performance: 10000 1726.95 µs/op

下面是核心代码,它基本上是在不同情况下将数据格式化为字符串。整个项目可以通过 https://github.com/tyrchen/pattern_match获得.
defmodule Ifelse do
def process(data) do
if is_list(data) do
data
|> Enum.map(fn(entry) ->
if is_tuple(entry) do
{k,v} = entry
"#{k}: #{v}" |> transform
else
entry |> process
end
end)
|> Enum.join("\n")
else
if is_map(data) do
data
|> Enum.map(fn({k, v}) -> transform("#{k}: #{v}") end)
|> Enum.join("\n")
else
data |> transform
end
end
end

defp transform(str) do
" #{str}"
end
end

defmodule Cond do
def process(data) do
cond do
is_list(data) ->
data
|> Enum.map(fn(item) ->
cond do
is_tuple(item) ->
{k, v} = item
"#{k}: #{v}" |> transform
true ->
item |> process
end
end)
|> Enum.join("\n")
is_map(data) ->
data
|> Enum.map(fn({k, v}) -> "#{k}: #{v}" |> transform end)
|> Enum.join("\n")
true ->
" #{data}"
end
end

defp transform(str) do
" #{str}"
end

end

defmodule Pattern do
def process(data) when is_tuple(data) do
{k, v} = data
"#{k}: #{v}" |> process
end

def process(data) when is_list(data) or is_map(data) do
data
|> Enum.map(fn(entry) -> process(entry) end)
|> Enum.join("\n")
end

def process(data) do
" #{data}"
end

end

我错过了什么吗?或者我需要更复杂的测试来找出 erlang VM 模式匹配的强度?

最佳答案

两点:

  • 为了让您看到任何好处,您需要进行大量测试,因为归根结底,条件检查是线性的(O(N)),而模式可以优化为二叉树搜索( O(log2N) )
  • 尽管如此,并非所有模式都可以同等优化。如果我没记错的话,guard 子句仍然是线性匹配的

  • 模式优化肯定会启动的一个更直接的例子是 Elixir 用于 Unicode 操作的模式:
    case codepoint do
    ?á -> ?Á
    ?é -> ?É
    ?í -> ?Í
    ...
    ?ū -> ?Ū
    end

    在这种情况下,VM 能够构建一棵树,而不是线性测试每个模式直到找到匹配的模式,二叉树将进行更快的查找。

    Erlang VM 也可能能够优化列表和元组内部的模式。鉴于模式匹配通常更具表现力,事实上它平均更快并且仅在最坏的情况下是线性的,这是一个非常好的优点。

    关于erlang - 为什么模式匹配性能并不比 elixir 中的 ifelse/cond 好多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28841522/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com