首页 > 解决方案 > Ocaml:使用通配符是否比在模式匹配中使用变量更有效?

问题描述

在使用 Ocaml 的模式匹配时,我有时会犹豫是否使用通配符 ( _),而是使用我可以为清楚起见命名的变量。我想知道它是否(尽管我认为稍微有点)效率低于使用它,因为使用通配符编译器知道该值将无法访问,并且没有创建指针。

考虑以下三个函数:

没有 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 文档,但找不到有关通配符实现的信息。

标签: performancepattern-matchingocamlwildcard

解决方案


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

例如,您的前两个示例使用非穷举模式匹配,因此编译器将添加一些额外的分支,这些分支会在运行时引发异常。显然,这些分支增加了可执行文件的大小。

即使您的模式匹配是详尽无遗的,也可能存在差异。在您的第三个示例中,您的 catch-all 分支导致编译器创建所有底层案例并让它们跳转到这个公共代码。如果您已经明确编写了所有分支,那么每个案例都将负责返回自己的结果。

So, depending on whether the compiler decides to perform jump/epilogue threading and block tail merging, your code might be more or less large, more or less fast. That said, there should be no difference on the memory consumption. But even that is not guaranteed, because code changes might in turn cause the inlining heuristics to diverge, and thus increase or decrease optimization opportunities.

To summarize, short of looking at the generated assembly code, it is hard to predict the decisions of the compiler, even on such simple functions.


推荐阅读