Ocaml。在模式匹配中使用通配符是否比使用变量更有效?

问题描述 投票:0回答:1

当使用Ocaml进行模式匹配时,我有时会对使用通配符(_),而是使用一个我可以命名的变量来明确。我想知道这是否(虽然我推测略微)比使用它的效率低,因为使用通配符,编译器知道该值不会被到达,并且没有创建指针。

考虑一下下面的三个函数。

No 1

let compare = function
        [], [] -> true
         |h::t, h2::t2 when h > h2 -> compare t t2
         |h::t, h2::t2 -> false

第2条

let compare = function
        [], [] -> true
         |h::t, h2::t2 when h > h2 -> compare t t2
         |_::_, _::_ -> false

第3条

let compare = function
        [], [] -> true
         |h::t, h2::t2 when h > h2 -> compare t t2
         |_ -> false

No3应该更快,但2是否比第一个更快,或使用更少的内存呢?我查阅了caml文档,却找不到关于通配符实现的信息。

performance pattern-matching ocaml wildcard
1个回答
1
投票

编译器并不真正关心未使用的变量是否出现在模式中。然而,它关心的是哪些分支存在以及它们的顺序。

例如,你的前两个例子使用了非详尽的模式匹配,所以编译器会添加一些额外的分支,在运行时引发异常。显然,这些分支会增加可执行文件的大小。

即使你的模式匹配是详尽的,也可能会有差异。在你的第三个例子中,你的 catch-all 分支导致编译器创建所有的底层情况,并使它们跳转到这个公共代码。如果你明确地写了所有的分支,那么每个case都会负责返回自己的结果。

所以,根据编译器是否决定执行跳转线程和块尾合并,你的代码可能会或大或小,或快或慢。也就是说,在内存消耗上应该没有区别。但即使是这样也不能保证,因为代码的变化可能会反过来导致内联启发式方法的分歧,从而增加或减少优化机会。

综上所述,如果不看生成的汇编代码,很难预测编译器的决定,即使是在这样简单的函数上。

© www.soinside.com 2019 - 2024. All rights reserved.