【发布时间】:2018-04-11 06:47:50
【问题描述】:
我写了 isPrime 函数。它检查给定的数字是否为素数。 最后一个“主要”列表是单独给出的。
prime :: [Integer]
prime = 2 : filter isPrime [3..]
isPrime :: Integer -> Bool
isPrime n | n < 2 = False
isPrime n = all (\p -> n `mod` p /= 0) . takeWhile ((<=n) . (^2)) $ prime
如果可能的话,我认为将两个函数合并为一个总是更好。所以我将 isPrime 和 prime 合并为一个函数 isPrime2。但是isPrime2的性能很差。
isPrime2 :: Integer -> Bool
isPrime2 n | n < 2 = False
isPrime2 n = all (\p -> n `mod` p /= 0) . takeWhile ((<=n) . (^2)) $ 2 : filter isPrime2 [3..]
isPrime 40000000000000000001
=> 0.5 秒
isPrime2 40000000000000000001
=> 19.8 秒
我的机器是 Ubuntu 17.10 x86-64。我正在使用 ghc 8.2.1。有谁知道为什么?
【问题讨论】:
-
我的猜测是,因为
prime是一个常数,它会被记忆,而isPrime2是一个函数,所以它不会。然而,这只是一个猜测...... -
谢谢!你的解释给了我洞察力。
-
@eii0000 你是在测试它编译还是解释?如果您将
isPrime2 n简化为all (\p -> n `mod` p /= 0) . takeWhile ((<=n) . (^2)) $ 2 : [3,5..],它如何比较? -
所有 (\p -> n
modp /= 0) 。 takeWhile (( nmodp /= 0) 。 takeWhile (( -
我编译了它。谢谢!
标签: performance haskell primes primality-test