I wrote two prime finder functions and the sieve only performs about 10% better. I'm using two optimizations for the simple version.
- Don't check even numbers
- Only check up to the square root or
j * j <= i
. ( equivalent )
and one optimization for the sieve version
- Only check up to the square root or
i * i <= n
. ( equivalent )
What optimizations can I add to the sieve?
My sieve is pretty slow. I don't want to do a bitwise implementation yet, I want to understand if this implementation offers any benefits.
Or if I missed an implementation point.
The inner for
loop in the pseudocode here looks interesting / odd
https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
I don't know how to interpret it. (update: the OP seems to indicate in the comments that it was an issue with incorrect formatting after copy-pasting the pseudocode from Wikipedia, and with the corrected formatting it is clear now)
Here it is:
algorithm Sieve of Eratosthenes is:
input: an integer n > 1. output: all prime numbers from 2 through n.
let A be an array of Boolean values, indexed by integers 2 to n, initially all set to true.
for i = 2, 3, 4, ..., not exceeding √n do if A[i] is true for j = i2, i2+i, i2+2i, i2+3i, ..., not exceeding n do A[j] := false
return all i such that A[i] is true.
// prime-2
// 2 optimizations - odds and square root
function prime2(n){
const primes = [2];
not_prime: for(let i = 3; i < n; i += 2){
for(let j = 2; j * j <= i; j++){
if(i % j === 0){
continue not_prime;
}
}
primes.push(i);
}
return primes;
}
// prime-3
// sieve implementation
function prime3 (n) {
const primes = [];
const sieve = (new Array(n)).fill(true);
for (let i = 2; i * i <= n; i += 1) {
if (sieve[i]) {
for (let j = i + i; j < n; j += i) {
sieve[j] = false;
}
}
}
makePrimes(sieve, primes, n);
return primes;
};
function makePrimes(sieve, primes, n){
for (let i = 2; i < n; i++) {
if(sieve[i]) {
primes.push(i);
}
}
}