提高Java中Eratosthenes代码的Sieve效率

时间:2012-02-22 18:23:57

标签: java performance sieve-of-eratosthenes

我在Java中使用Sieve of Eratosthenes的代码,但是我面临一些时间和空间效率问题。 这是代码:

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);
    }
}

对于高达10 ^ 3的输入似乎工作正常,在10 ^ 4时它只是挂起而在10 ^ 5及以上我得到OutOfMemoryError。 而且代码似乎工作正常,但我想把它加紧一点。有什么建议吗?

5 个答案:

答案 0 :(得分:4)

您正在该代码中装箱/取消装箱 ton 。您可能想尝试用基本类型的直数组替换ArrayList<>

答案 1 :(得分:3)

不使用偶数加倍速度。

答案 2 :(得分:3)

一种可能的优化方法是使用基本类型数组替换ArrayLists,前提是您事先知道所需数组的大小。这样可以防止代码中当前存在的所有值的不必要的装箱/取消装箱。

另外,请注意,您不必在数组中存储偶数,只需要奇数 - 这样做会将内存需求的处理时间缩短一半。

为了解决OutOfMemoryError,你可以在启动时摆弄JVM的配置参数,为应用程序提供更多的堆空间。

答案 3 :(得分:1)

您的代码所做的工作远远超出了需要。你只需要一个布尔数组,两个循环来标记非素数,另一个循环来打印素数的索引号。像这样:

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 + " ");
}

答案 4 :(得分: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*/