performance - 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 文档,但找不到有关通配符实现的信息。
解决方案
编译器并不真正关心未使用的变量是否出现在模式中。但是,它确实关心存在哪些分支及其顺序。
例如,您的前两个示例使用非穷举模式匹配,因此编译器将添加一些额外的分支,这些分支会在运行时引发异常。显然,这些分支增加了可执行文件的大小。
即使您的模式匹配是详尽无遗的,也可能存在差异。在您的第三个示例中,您的 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.
推荐阅读
- python - 列表理解中的匹配、过滤和分组
- r - R中的隐式字符强制:为什么“4”> 10 == TRUE?
- postgresql - 聊天(投票过程)无法正常工作。错误 500
- android - 增加选定底部导航项的大小
- keras - 通过改变学习率,每个 epoch 的训练时间急剧减少
- c# - 在迁移时使用 ef core 插入数据的问题
- azure-active-directory - AzureActiveDirectory - 禁用选择帐户
- asp.net-mvc - JavaScript 语言服务已被禁用,有人有这方面的经验吗?
- mysql - 如何将 json 值添加到 db 列?
- c# - 在 XMLDocument 上加载 url 时出现 (500) 内部服务器错误