++,最后一个& amp;初始化比:,head& amp;更快尾巴? [英] ++, last & init faster than :, head & tail?

查看:48
本文介绍了++,最后一个& amp;初始化比:,head& amp;更快尾巴?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑到以下两种编写函数的方法,该函数可以找到所有素数直至特定数字:

Given these two ways of writing a function that finds all primes up to a specific number:

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 & primesTo2 中使用的 tail .

Why is primesTo1 a lot faster than primesTo2, even though the different functions used; primesTo1 uses ++, last & init instead of :, head & tail used in primesTo2.

带有:set + s ghci 的输出:

*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寻找最佳的质数生成器,我只是对两个函数的速度差异感到困惑.


Note: I'm not looking for an optimal prime number generator for Haskell, I'm just confused by the speed differences of the two functions.

推荐答案

"nm"指出,其原因是 primes2 首先尝试除以找到的最大质数,而 primes1 从最低的开始.

As pointed out by the "n.m.", the reason for this is that primes2 first tries to divide by the largest found primes, while primes1 starts with the lowest.

因此,首先反转当前素数的列表,然后在 all 中使用它们实际上比 primes1 primes2 都快:

So first reversing the list of current primes, before using them in all is actually faster than both primes1 and primes2:

primes3 = iterate
    (\ps -> ([x |
            x <- [head ps + 1..],
            all (\p -> x `mod` p /= 0) $ reverse ps] !! 0)
        : ps)
    [2]

primesTo3 :: Integer -> [Integer]
primesTo3 n = tail $ head $ dropWhile (\p -> head p <= n) primes3

10000 作为参数的

ghci 速度:

*Main> primesTo3 10000
...
(0.41 secs, 241128512 bytes)

并使用 ghc -O2 进行编译:

$ time ./primes3
...
./primes  0.05s user 0.00s system 24% cpu 0.209 total

这篇关于++,最后一个&amp; amp;初始化比:,head&amp; amp;更快尾巴?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆