Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 模式匹配中的性能_Performance_Haskell_Pattern Matching - Fatal编程技术网

Performance 模式匹配中的性能

Performance 模式匹配中的性能,performance,haskell,pattern-matching,Performance,Haskell,Pattern Matching,我正在阅读,特别是关于模式匹配的章节。以下是教程中提供的用于计算列表长度的代码: length' :: (Num b) => [a] -> b length' [] = 0 length' (_:xs) = 1 + length' xs 我的问题是,反转递归顺序(通过将基本情况放在下面)是否会显示任何显著的性能提高 length' :: (Num b) => [a] -> b length' (_:xs) = 1 + length' xs length' []

我正在阅读,特别是关于模式匹配的章节。以下是教程中提供的用于计算列表长度的代码:

length' :: (Num b) => [a] -> b  
length' [] = 0  
length' (_:xs) = 1 + length' xs
我的问题是,反转递归顺序(通过将基本情况放在下面)是否会显示任何显著的性能提高

length' :: (Num b) => [a] -> b
length' (_:xs) = 1 + length' xs
length' [] = 0

不,这不会带来任何性能提升。在这两种情况下,编译器都必须对其WHNF的参数求值,以检查它是否为空列表

实际上,这个函数很可能会在编译过程中被重写,生成与您编写的代码完全不同的代码(假设您使用优化编译)

查看生成的核心(编译时未进行优化):

我们可以看到编译器生成了等价的语句。仅供参考,代码如下:

main = do
         print $ f1 [1..100]
         print $ f2 [1..100]

f1 [] = 0
f1 (_:xs) = 1 + f1 xs
f2 (_:xs) = 1 + f2 xs
f2 [] = 0

使用
ghc-ddump siml file.hs编译

仅使用两种情况,顺序并不重要。对于三种情况,顺序不会影响性能,但可以简化代码。例如,假设您有一个函数,它对空列表或单例列表执行大致相同的操作,但在包含2个或更多项的列表上递归。您可以编写从最简单到最复杂的模式:

foo [] = []
foo [x] = [x]
foo (x:y:rest) = x+y : foo (y:rest)
或者,您可以通过先处理更复杂的一个案例,将其减少为两个案例:

foo (x:y:rest) = x+y : foo (y:rest)
foo short = short

由于
foo=id
适用于这两种短情况。

还有一个不重要的必要原因:模式匹配(在GHC中)非常重要。
foo (x:y:rest) = x+y : foo (y:rest)
foo short = short