IE,
What am I doing wrong here? Does it have to to with lists, sequences and arrays and the way the limitations work?
So here is the setup: I’m trying to generate some primes. I see that there are a billion text files of a billion primes. The question isn’t why…the question is how are the guys using python calculating all of the primes below 1,000,000 in milliseconds on this post…and what am I doing wrong with the following F# code?
let sieve_primes2 top_number =
let numbers = [ for i in 2 .. top_number do yield i ]
let sieve (n:int list) =
match n with
| [x] -> x,[]
| hd :: tl -> hd, List.choose(fun x -> if x%hd = 0 then None else Some(x)) tl
| _ -> failwith "Pernicious list error."
let rec sieve_prime (p:int list) (n:int list) =
match (sieve n) with
| i,[] -> i::p
| i,n' -> sieve_prime (i::p) n'
sieve_prime [1;0] numbers
With the timer on in FSI, I get 4.33 seconds worth of CPU for 100000… after that, it all just blows up.
Your sieve function is slow because you tried to filter out composite numbers up to
top_number. With Sieve of Eratosthenes, you only need to do so untilsqrt(top_number)and remaining numbers are inherently prime. Suppose we havetop_number = 1,000,000, your function does78498rounds of filtering (the number of primes until1,000,000) while the original sieve only does so168times (the number of primes until1,000).You can avoid generating even numbers except 2 which cannot be prime from the beginning. Moreover,
sieveandsieve_primecan be merged into a recursive function. And you could use lightweightList.filterinstead ofList.choose.Incorporating above suggestions:
In my machine, the updated version is very fast and it completes within 0.6s for
top_number = 1,000,000.