Ocaml:在模式匹配中使用通配符比使用变量更有效吗?

Ocaml: Is using the wildcard more efficient than using a variable in a pattern matching?

在 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 应该更快,但是 2faster and/or 使用的内存比第一个少吗? 我仔细研究了 caml 文档,但找不到有关通配符实现的信息。

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

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

即使您的模式匹配是详尽无遗的,仍然可能存在差异。在你的第三个例子中,你的包罗万象的分支导致编译器创建所有底层案例并使它们跳转到这个公共代码。如果您明确编写了所有分支,那么每个案例都会负责返回自己的结果。

因此,根据编译器是否决定执行 jump/epilogue 线程和块尾部合并,您的代码可能或多或少变大,或快或变快。也就是说,内存消耗应该没有区别。但即使这样也不能保证,因为代码更改可能反过来导致内联启发式算法发散,从而增加或减少优化机会。

总而言之,如果不查看生成的汇编代码,就很难预测编译器的决定,即使是在如此简单的函数上。