假设我们有几种function heads
或case do
模式可以匹配。
首先放置“常见情况” 或“最可能” 标头会带来好处吗?
在ELIXIR中对case do
匹配模式进行重新排序时,我看到了时序方面的改进,将最常见的模式放在第一位。
我原本希望VM对此进行优化,顺序无关紧要。
示例:
for {s, i} <- li do
case :binary.split(s, spliter, [:global]) do
[_, tag, val, _, _] ->
# this pattern occurs over 9/10 times.
# in files with over 100000 rows matching this pattern
# reduced processing time
{:tv, i, tag, val}
[_, "data", _] ->
Process.put(:data_tag, true)
{:tb, i, "data"}
[_, "/data", _] ->
Process.put(:data_tag, false)
{:te, i, "data"}
[_, "/" <> tag, _] ->
if Process.get(:data_tag) do
{nil, i}
else
{:te, i, tag}
end
[_, "?xml" <> _, _] ->
{nil, i}
[_, "!--" <> _, _] ->
{nil, i}
[_, "return" <> _, _] ->
{nil, i}
[_, tag, _] ->
if Process.get(:data_tag) do
{:tv, i, tag, ""}
else
{:tb, i, tag}
end
_ ->
{nil, i}
end
end
答案 0 :(得分:4)
除了可读性之外,没有任何好处。 Elixir仍然可以编译为Erlang抽象语法树,并且Erlang编译器允许自己对子句进行重新排序,以使其尽可能高效。
在较早版本的编译器中,guard子句可能会干扰此功能,因此在将所有非guard子句设置在顶部附近时,您将具有一个优势,但是对Erlang编译器的不断改进使其不太可能优化。
仍然,正如您所发现的那样,在更广泛的分支情况下,编译器看不到真正明显的改善运行时间的方法(例如,检查相同确切类型的多个文字),您可能会发现好处
答案 1 :(得分:3)
您对Erlang编译器的期望很高:)
尽管到目前为止给出的答案肯定是正确的,并且Erlang编译器可能会对子句进行重新排序,但是它无法预测您的输入中哪些二进制文件会更频繁。
也就是说,人们可能希望对具有不同保护措施和/或互斥的子句进行优化,但是编译器无法知道您比"?xml"
更频繁地收到"data"
。