【问题标题】:What kind of optimizations does Haskell do here?Haskell 在这里做了哪些优化?
【发布时间】:2014-06-23 22:14:09
【问题描述】:

所以,我承认我是 Haskell 新手,但到目前为止我非常喜欢它,因为我最近一直在挥霍质数。 (这就是让我喜欢它的原因)

我有这个相对基本的脚本。它完全按照应有的方式工作,即使它不是尽可能高效。不过,这不是我的问题。这是我的脚本:

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))

就像我说的,很简单。 oddFactors 遍历从 3sqrt(p) 的奇数,如果它是 p 的因子,则将其添加到列表中。

primes2^x -1 上调用oddFactors 并检查结果列表是否等于空列表。

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

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

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

【问题讨论】:

  • 这几乎与这个问题完全相同:stackoverflow.com/questions/24263611/…
  • 谢谢!找不到任何东西
  • 顺便说一句,不要写l == []。它与null l 相同,但不要求列表的元素类型具有Eq 实例。

标签: haskell


【解决方案1】:

测试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(或更准确地说,整个list spine)之前强制计算整个列表。

【讨论】:

    【解决方案2】:

    Haskell 懒惰地评估函数调用。这意味着它在评估时首先尝试找出==“调用”,比如prime 60,它试图找到1152921504606846975的奇数因子。在评估它时,它将下降到== 定义,对于一个空列表,它只尝试确定是否至少有一个元素。如此有效,它只评估是否

    1152921504606846975 `mod` 3 == 0
    

    既然这是真的,它甚至不评估列表的其余部分:它已经知道 3:(stuff) == []False,不管 (stuff) 可能评估什么。

    当你传递61 时,它试图找到2305843009213693951 的奇数因子,它是一个素数,所以它必须扩展洞列表推导式,以找出它是空的。这就是为什么需要这么长时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 1970-01-01
      • 2011-11-10
      • 2012-05-13
      • 2010-10-30
      • 2010-09-27
      • 1970-01-01
      相关资源
      最近更新 更多