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