Site With The Lamp

A LAMP Portal


Linux
Java
PHP


Blog
etc

The totally Rad Software Company - Sponsor

Sieve of Eratosthenes

More Articles

Strange Characters and Blobs

perl File upload progress bar.

LPI Certification

In the previous step we created a simple stored procedure that generated prime numbers and saved them in a table of a database. Well it doesn't actually generate primes but it uses the Sieve of Eratosthenes to separate the primes from the composites.

We will optimize this stored procedure by first making sure we do not sieve what has already been sieved. Suppose we are looking to delete numbers that can be divided by n; any surviving number in our table would be one that cannot be divided by (n-1) which implies that the first composite will be n^2

The second optimization is to skip over the numbers that are already in the table from previous sieving attempts. Combining these optimizations together yields the following code:


    DECLARE sqrt_p INT;
    DECLARE i INT;
    DECLARE minp INT;

    SELECT IFNULL(MAX(value),1) INTO minp FROM primeNumbers;
    
    IF P > minp THEN
        # don't bother, we already have this in the table.
        SET sqrt_p = CEIL(SQRT(P));
        
        IF minp < 2 THEN
            # starting from an empty table
            INSERT INTO primeNumbers(value) VALUES(2);
            SET i=3;
        ELSE
            IF (i%2 = 0) THEN
                SET i = minp+1;
            ELSE
                SET i = minp+2;
            END IF;
        END IF;            

        WHILE i <= P DO
            # populate table with all odd numbers. Later we delete non primes.
            INSERT INTO primeNumbers(value) VALUES(i);
            SET i = i+2;
        END WHILE;

        SET i=3;

        # now composite numbers greater than minp will be deleted.
        WHILE i < sqrt_p DO
            IF (minp < (i*i -1)) THEN
                # we don't want to sieve what has already been sieved
                SET minp = i*i -1;
            END IF;           
            DELETE FROM primeNumbers WHERE value > minp AND (value%i)=0;
            SET i = i+2;
        END WHILE;
    END IF; 
    

We are still dividing by all the integers but the reality is that with the Sieve of Eratosthenes you only need to use the known primes as the divisors.

    WHILE i < sqrt_p DO
        IF (minp < (i*i -1)) THEN
            # we don't want to sieve what has already been sieved
            SET minp = i*i -1;
        END IF;

        # are we dividing by a prime?
        SELECT IFNULL(value,0) INTO itest FROM primeNumbers WHERE value=i;
        IF itest > 0 THEN
            DELETE FROM primeNumbers WHERE value > minp AND (value%i)=0;
        END IF;
        SET i = i+2;
    END WHILE;

We can try to improve this code a bit more but that would be nitpicking. On my ancient server it finds all the primes under 1,000,000 in less than 3 minutes. But can it be faster? Well there is another algorithm that's a bit faster. We will have a look into that later.

See also: PHP version