哪个在Haskell中效率更高;模式匹配或嵌套if / case语句?

时间:2021-03-13 08:52:28

I'm just curious about the efficiency of pattern matching in Haskell. What is a simple case of where pattern matching would be better than nested if/case statements and then the converse?

我只是对Haskell中模式匹配的效率感到好奇。什么是模式匹配比嵌套的if / case语句更好的简单情况,然后是相反的?

Thanks for your help.

谢谢你的帮助。

3 个解决方案

#1


In Haskell, case and pattern matching are inextricably linked; you can't have one without the other. if p then e1 else e2 is syntactic sugar for case p of { True -> e1; False -> e2 }. For these reasons, I think it is impossible to produce the examples you ask for; in Core Haskell, everything is equivalent to case.

在Haskell中,案例和模式匹配是密不可分的;你不能没有另一个。如果p那么e1,否则e2是{True - > e1的情况p的语法糖;错 - > e2}。由于这些原因,我认为不可能提出你要求的例子;在Core Haskell中,一切都等同于案例。

In languages in the ML family, the optimizer can often do very impressive things with complex pattern matches. This is more difficult for Haskell compilers; because of lazy evaluation, the pattern-match compiler is not allowed to reorder certain tests. In other words, if you nest case statements in different ways, you may get different performance, but in Haskell you also get different semantics. So generally the compiler doesn't mess with it.

在ML系列的语言中,优化器通常可以通过复杂的模式匹配来完成令人印象深刻的事情。对于Haskell编译器来说这更难一些;由于延迟评估,模式匹配编译器不允许重新排序某些测试。换句话说,如果以不同的方式嵌套case语句,则可能会获得不同的性能,但在Haskell中,您也会得到不同的语义。所以通常编译器不会搞乱它。

As far as which way to write your own code, it's safe to assume that the code with the fewest case expressions is the best (keeping in mind that one if is equivalent to one case expression).

至于编写自己的代码的方式,可以安全地假设具有最少案例表达式的代码是最好的(记住一个if等同于一个case表达式)。

#2


I didn't confirm this, but I think both forms will become a nested case-of expression when translated to core Haskell by the compiler. The best way to find out is asking the compiler itself. In GHC you can turn on the dump of the core intermediate program by using the arguments:

我没有证实这一点,但我认为这两种形式在编译器转换为核心Haskell时将成为嵌套的表达式。找出答案的最好方法是询问编译器本身。在GHC中,您可以使用以下参数打开核心中间程序的转储:

  • Before simplifications: -ddump-ds
  • 在简化之前:-ddump-ds

  • After simplifications: -ddump-simpl
  • 简化后:-ddump-simpl

#3


According to the specification, they are semantically equivalent. This, of course, does not necessarily mean that they are implemented identically, but I would personally be surprised if there was a difference in a decent compiler.

根据规范,它们在语义上是等价的。当然,这并不一定意味着它们的实现方式相同,但如果一个体面的编译器存在差异,我个人会感到惊讶。

#1


In Haskell, case and pattern matching are inextricably linked; you can't have one without the other. if p then e1 else e2 is syntactic sugar for case p of { True -> e1; False -> e2 }. For these reasons, I think it is impossible to produce the examples you ask for; in Core Haskell, everything is equivalent to case.

在Haskell中,案例和模式匹配是密不可分的;你不能没有另一个。如果p那么e1,否则e2是{True - > e1的情况p的语法糖;错 - > e2}。由于这些原因,我认为不可能提出你要求的例子;在Core Haskell中,一切都等同于案例。

In languages in the ML family, the optimizer can often do very impressive things with complex pattern matches. This is more difficult for Haskell compilers; because of lazy evaluation, the pattern-match compiler is not allowed to reorder certain tests. In other words, if you nest case statements in different ways, you may get different performance, but in Haskell you also get different semantics. So generally the compiler doesn't mess with it.

在ML系列的语言中,优化器通常可以通过复杂的模式匹配来完成令人印象深刻的事情。对于Haskell编译器来说这更难一些;由于延迟评估,模式匹配编译器不允许重新排序某些测试。换句话说,如果以不同的方式嵌套case语句,则可能会获得不同的性能,但在Haskell中,您也会得到不同的语义。所以通常编译器不会搞乱它。

As far as which way to write your own code, it's safe to assume that the code with the fewest case expressions is the best (keeping in mind that one if is equivalent to one case expression).

至于编写自己的代码的方式,可以安全地假设具有最少案例表达式的代码是最好的(记住一个if等同于一个case表达式)。

#2


I didn't confirm this, but I think both forms will become a nested case-of expression when translated to core Haskell by the compiler. The best way to find out is asking the compiler itself. In GHC you can turn on the dump of the core intermediate program by using the arguments:

我没有证实这一点,但我认为这两种形式在编译器转换为核心Haskell时将成为嵌套的表达式。找出答案的最好方法是询问编译器本身。在GHC中,您可以使用以下参数打开核心中间程序的转储:

  • Before simplifications: -ddump-ds
  • 在简化之前:-ddump-ds

  • After simplifications: -ddump-simpl
  • 简化后:-ddump-simpl

#3


According to the specification, they are semantically equivalent. This, of course, does not necessarily mean that they are implemented identically, but I would personally be surprised if there was a difference in a decent compiler.

根据规范,它们在语义上是等价的。当然,这并不一定意味着它们的实现方式相同,但如果一个体面的编译器存在差异,我个人会感到惊讶。