3

I've worked upon a code for Sieve of Eratosthenes in Java, but I face a few time and space efficiency issues. Here's the code :

import java.util.*;

class EratosthenesSeive
{

    public static void main(String args[])
    {

        ArrayList<Long> myPrimeList = new ArrayList<Long>();
        ArrayList<Long> myTempPrimeList = new ArrayList<Long>();
        ArrayList<Boolean> isPrimeNumber = new ArrayList<Boolean>();
        int index = 0;

        long ul = 1500l;
        long ll = 2;

        do
        {
            myTempPrimeList.add(ll);
            isPrimeNumber.add(true);
            ll++;
        }while( ll != (ul+1));

        for(long i : myTempPrimeList)
        {
            if(isPrimeNumber.get(index))
            {
                myPrimeList.add(i);
                for(long j = i ; j*i <= ul; j++)
                {
                    isPrimeNumber.set(myTempPrimeList.indexOf(j*i),false);
                }
            }
            index++;
        }

        System.out.println(myPrimeList);
    }
}

It seems to be working fine for input upto 10^3, at 10^4 it simply hangs and at 10^5 and above I get OutOfMemoryError. And the code seems to be working alright, but I would like to fasten it up a bit more. Any suggestions?

Kazekage Gaara
  • 14,972
  • 14
  • 61
  • 108

5 Answers5

4

You are boxing/unboxing a ton in that code. You may want to try replacing the ArrayList<>s with straight arrays of the primitive type.

dlev
  • 48,024
  • 5
  • 125
  • 132
3

Double the speed by not working with even numbers.

Erik Ekman
  • 2,051
  • 12
  • 13
3

One possible optimization would be replacing the ArrayLists with arrays of primitive types, given that you know beforehand the size of the arrays needed. This will have the effect of preventing all the unnecessary boxing/unboxing of values currently present in your code.

Also, be aware that you don't have to store even numbers in the array, only odd numbers - doing so will reduce the memory requirements and processing time by half.

For solving the OutOfMemoryError you can fiddle with the JVM's configuration parameters at startup, making available more heap space for the application.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
1

Your code is doing a lot more work than it needs to. You just need a single array of booleans, two loops to mark the non-prime numbers and another loop to print the index numbers of the primes. Like this:

public void printPrimes(int max) {

    // declare a single array of booleans
    boolean[] primeFlags = new boolean[max + 1];

    // double loop sieve-style and mark non-primes as true
    for (int m = 2; m <= (int)Math.sqrt(max); m++) 
        for (int k = m*m; k <= max; k += m) primeFlags[k] = true;

    // loop over bool array and print indexes with false values 
    // which will be the prime numbers
    for (int m = 2; m <= max; m++)
        if (!primeFlags[m]) System.out.print(m + " ");
}
Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
0
import java.util.Scanner;

//Sieve Of Erastothenes

public class SieveOfErastothenes {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter a range n : ");
        int n = sc.nextInt();

        boolean ar[] = new boolean[n+1];
        for (int i=2;i<=n;i++)
        ar[i] = true;

        for(int i = 2;i*i<=n;i++)
        {
            if(ar[i])
            {
                for(int j=i;i*j<=n;j++)
                    ar[i*j]=false;
            }
        }

        for(int i=2;i<=n;i++)
        {
            if(ar[i])
                System.out.print(i+" ");
        }
        sc.close();

    }

}

/*This code is contributed by Asish Samantaray*/
ppovoski
  • 4,553
  • 5
  • 22
  • 28
Asish
  • 1
  • 2