Can the execution time of this prime number generator be improved?

后端 未结 5 2168
情书的邮戳
情书的邮戳 2020-12-30 09:22

My initial goal when writing this was to leave the smallest footprint possible. I can say with confidence that this goal has been met. Unfortunately, this leaves me with a r

5条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-30 10:13

    The imperative version posted by Yin is very fast. On my machine it is also about 0.5sec. However, if you want to write a simple functional solution you can just write this:

    let isPrime(n) =
      let ms = int64(sqrt(float(n)))
      let rec isPrimeUtil(m) =
        if m > ms then true
        elif n % m = 0L then false
        else isPrimeUtil(m + 1L)
      (n > 1L) && isPrimeUtil(2L)
    
    [ 1L .. 2000000L ] |> List.filter isPrime
    

    This simply tests whether a number is a prime for all numbers to 1 milion. It doesn't use any sophisticated algorithms (it's actually funny that a solution which is simplest is often good enough!). On my machine, your updated version runs about 11 seconds and this runs about 2 seconds.

    More interestingly, this is very easy to parallelize. If you use PLINQ you can write the version below and it will run almost 2 times faster on dual core. This means that on quad core, it could be as fast as the fastest solution from all the answers here, but with minimal programming effort :-) (of course, using four cores is not ecological, but.. well)

    [ 1L .. 2000000L ] |> PSeq.ofSeq |> PSeq.filter isPrime |> List.ofSeq
    

    The PSeq functions are wrappers for PLINQ that I created for my book (it makes using PLINQ from F# more natural). They are available in source code for Chapter 14.

提交回复
热议问题