Jump to content

Sieve of Eratosthenes: Difference between revisions

m
→‎With Wheel: Haskell - minor touch-ups and comments...
(→‎With Wheel: Haskell Tree-Folding: minor edits...)
m (→‎With Wheel: Haskell - minor touch-ups and comments...)
Line 5,625:
The above example has been left to show its problems, as follows:
 
1. The generation of the wheel works just to generate a small wheel list of primes which has been directly inserted into the code as here, but is very inefficient for generation of large wheels such as the 2/3/5/7/11/13/17 wheel, which has 92160 cyclic elements; this is due to it using essentially a trial division to determine the wheel (Greatest Common Divisor - gcd - works by repeated division). A programmatic wheel generator based on sieve culling is much better as to performance and can be used without inserting the generated table.
 
2. The above routine uses ridiculous means to re-generatedgenerate the position on the wheel for the recursive base primes in the use of `dropWhile`, etc. The below improved code uses a copy of the place in the wheel for each found base prime for ease of use in generating the composite number to-be-culled chains.
 
<lang haskell>-- autogenerates wheel primes, first sieve prime, and gaps
Line 5,663:
x : (union xs . _U . pairs) t where -- tree-shaped folding big union
pairs (xs:ys:t) = union xs ys : pairs t -- ~= nub . sort . concat
union xs@(x:xs') ys@(y:ys') =
if| x < y then= x : union xs' ys else
if| y < x then= y : union xs ys' else
| otherwise = x : union xs' ys' -- x and y must be equal!</lang>
 
TheWhen compiled with -O2 optimization and -fllvm (the LLVM back end), the above code is over twice as fast as the Odds-Only version andas it should be as that is probablyabout the fastestratio purelyof functionalreduced incrementaloperations sieveminus heresome slightly increased operation complexity, sieving the primes to a 100hundred million in about tenseven seconds on a modern middle range desktop computer. It is almost twice as fast as the "primesW" version due to the increased algorithmic efficiency!
 
Note that the "wheelGen" code could be used to not need to do further culling at all by continuously generating wheels until the square of the "firstSievePrime| is greater than the range as there are no composites left up to that limit, but this is always slower than a SoE due to the high overhead in generating the wheels - this would take a wheel generation of 1229 (number of primes to the square root of a hundred thousand is ten thousand) to create the required wheel sieved to a hundred million; however, the theoretical (if the time to advance through the lists per element were zero, which of course it is not) asymptotic performance would be O(n) instead of O(n log (log n)) where n is the range sieved. Just another case where theory supports (slightly) reduced number of operations, but practicality means that the overheads to do this are so big as to make it useless for any reasonable range ;-) !
 
===Priority Queue based incremental sieve===
474

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.