hra*_*234 4 performance ocaml functional-programming if-statement pattern-matching
假设我们有一个名为 d 的类型:
type d = D of int * int
Run Code Online (Sandbox Code Playgroud)
我们想要对其进行一些模式匹配,这样是不是更好:
let dcmp = function
| D (x, y) when x > y -> 1
| D (x, y) when x < y -> -1
| _ -> 0
Run Code Online (Sandbox Code Playgroud)
或者
let dcmp = function
| D (x, y) ->
if x > y then 1 else if x < y then -1 else 0
Run Code Online (Sandbox Code Playgroud)
一般而言,将模式与许多“when”情况匹配或匹配一个模式并在其中放入“if-then-else”会更好吗?
我在哪里可以获得有关此类问题的更多信息,例如 OCaml 和语法糖等的良好实践?
两种方法各有利弊,因此应根据具体情况使用。
该when子句更容易理解,if因为它只有一个分支,因此您可以一次消化一个分支。其代价是,当我们分析一个子句以了解其路径条件时,我们必须分析它之前的所有分支(并否定它们),例如,将您的变体与以下定义进行比较,这是等效的,
let dcmp = function
| D (x, y) when x > y -> 1
| D (x, y) when x = y -> 0
| _ -> -1
Run Code Online (Sandbox Code Playgroud)
当然,对于if/then/else构造来说也是如此,只是更难意外地重新排列if/then/else表达式中的分支(例如,在重构期间)并完全改变表达式的逻辑。
此外,when防护措施可能会阻止编译器执行决策树优化1并混淆2反驳机制。
考虑到这一点,在这个特定的例子中使用when代替的唯一优点if是when语法看起来更有吸引力,因为它完美地排列在一起,并且人脑更容易找到条件及其对应的值在哪里,即,它看起来更像真值表。但是,如果我们写
let dcmp (D (x,y)) =
if x = y then 0 else
if x > y then 1 else -1
Run Code Online (Sandbox Code Playgroud)
我们可以达到相同水平的可读性。
when总而言之,当不可能或几乎不可能用 表达相同的代码时,最好使用if/then/else. 为了提高可读性,最好将逻辑分解到具有可读名称的辅助函数中。例如,dcmp最好的解决方案是不使用if或when,例如,
let dcmp (D (x,y)) = compare x y
Run Code Online (Sandbox Code Playgroud)
1)when在这种特殊情况下,编译器将为和生成相同的代码if/then/else。但在更一般的情况下,防护可能会阻止匹配编译器生成有效的代码,特别是当分支不相交时。在我们的例子中,编译器只是注意到我们正在重复相同的分支,并将它们合并成一个分支,然后将其返回到 if/then/else 表达式,例如,这里是带有守卫的函数的 cmm 输出when,
(if (> x y) 3 (if (< x y) -1 1))
Run Code Online (Sandbox Code Playgroud)
这与该函数的 if/then/else 版本生成的代码完全相同dcmp。
2)当然,不是到它不会注意到丢失分支的状态,而是到它会不太准确地报告丢失分支或会要求您添加不必要的分支的状态。
| 归档时间: |
|
| 查看次数: |
3843 次 |
| 最近记录: |