给定这两种编写函数的方法,该函数可以找到直到特定数字的所有素数:
primes1 = iterate
(\ps -> ps ++ [([x |
x <- [last ps + 1..],
all (\p -> x `mod` p /= 0) ps] !! 0)])
[2]
primesTo1 :: Integer -> [Integer]
primesTo1 n = init $ head $ dropWhile (\p -> last p <= n) primes1
primes2 = iterate
(\ps -> ([x |
x <- [head ps + 1..],
all (\p -> x `mod` p /= 0) ps] !! 0)
: ps)
[2]
primesTo2 :: Integer -> [Integer]
primesTo2 n = tail $ head $ dropWhile (\p -> head p <= n) primes2
为什么primesTo1
比 快很多primesTo2
,即使使用了不同的功能;primesTo1
使用++
, last
&init
代替:
, head
&tail
用于primesTo2
.
ghci
的输出:set +s
:
*Main> primesTo1 10000
...
(0.51 secs, 124779776 bytes)
*Main> primesTo2 10000
...
(3.30 secs, 570648032 bytes)
编译ghc -O2
:
$ time ./primes1
...
./primes1 0.06s user 0.00s system 68% cpu 0.089 total
$ time ./primes2
...
./primes2 0.28s user 0.00s system 98% cpu 0.283 total
注意:我不是在为 Haskell 寻找最佳素数生成器,我只是对这两个函数的速度差异感到困惑。