繁体   English   中英

Haskell在这里做了什么样的优化?

[英]What kind of optimizations does Haskell do here?

因此,我当然是Haskell Newbie的成员,但是到目前为止,我非常喜欢它,因为我最近一直在进行素数激增。 (这是让我着迷的原因)

我有这个相对基本的脚本。 即使它效率不高,它也可以正常工作。 那不是我的问题。 这是我的脚本:

import System.Environment


oddFactors p = [x | x<- [3,5..floor (sqrt (fromIntegral p))], p `mod` x == 0]
prime x = oddFactors (2^x -1) == []

main = do
    args <- getArgs
    print (prime (read (head args) :: Int))

就像我说的那样,很简单。 奇数oddFactors3sqrt(p)奇数,如果它是p的因数,则将其添加到列表中。

primes调用2^x -1上的oddFactor ,并检查结果列表是否等于空列表。

奇怪的是,它似乎已经被优化了。 对于primes ,例如61,我的程序需要49秒才能运行并返回True。 但是,如果我执行60或62,则需要运行0.005秒并返回False。 这些是正确的返回值,但是我很好奇它是否经过某种方式的优化,因为它知道它只是在寻找一个匹配[]的列表,并且在找到一个列表之后,它会返回false,因为列表永远不会是[]

冗长的问题,但到目前为止,我也愿意对我的代码提出任何建议。 我大约两个小时前就接过Haskell,所以要好:)

编辑 :我当然知道我可以使用更好的东西作为初等性测试,例如Miller-Rabin,但这不是重点;)

测试list == []将评估list作为需要检查的空虚只有尽可能多的list 从技术上讲,尽可能多地发现list的最外层构造函数(可以是:[] ),使list成为弱头范式(WHNF)。

例如, (error "hello" : error "world") == []将返回False而不评估error表达式。

这是由于表达式被懒惰地求值以及(==)的定义以自然方式使用模式匹配导致的:

[]     == []     = True
[]     == _      = False
_      == []     = False
(x:xs) == (y:ys) = x==y && xs==ys

相比之下,如果定义是

[]     == []     = True
[]     == (y:ys) = []==ys && False
(x:xs) == []     = xs==[] && False
(x:xs) == (y:ys) = x==y && xs==ys

那么list == []将在返回False (或更确切地说,整个列表spine )之前强制执行整个列表的计算。

Haskell懒惰地评估函数调用。 这意味着它首先在求值时尝试找出== “ call”,例如说prime 60它试图找到1152921504606846975的奇数因子。 在评估时,它会归入==定义,对于一个空列表,它仅试图找出是否存在至少一个元素。 所以有效地它只会评估

1152921504606846975 `mod` 3 == 0

由于这是真的,所以它甚至不评估列表的其余部分:它已经知道3:(stuff) == []False ,而不管(stuff)可能会得出什么结果。

当您将其传递给61 ,它会尝试找到一个为质数的2305843009213693951的奇数因子,因此它必须扩展对孔列表的理解,才能确定其为空。 这就是为什么要花这么长时间的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM