PlanetXML

Primzahlen berechnen in C, C# und JAVA

Hier mal wieder ein Benchmark um die Geschwindigkeit von C, C# und Java zu vergleichen. Das Programm berechnet Primzahlen einmal mit dem Sieb des Eratosthenes und einmal nach einer Brute-Force Methode.

Die verwendeten Compiler und Parameter:

Java HotSpot(TM) Server VM (build 1.5.0_04-b05, mixed mode)
Microsoft (R) Visual C# .NET-Compilerversion 7.10.3052.4
gcc (GCC) 3.4.2 (mingw-special)
gcj (GCC) 3.4.2 (mingw-special)

javac PrimeSieve.java
csc PrimeSieve.cs /o
gcc primesieve.c -o primesieve.exe -O3 -march=pentium4 -std=c99
gcj PrimeSieve.java -o PrimeSieve.exe -O3 -march=pentium4 --main=PrimeSieve

Ergebnisse

Der Test wurde auf einem Notebook mit Pentium4 Mobile Prozessor 1.8 GHz durchgeführt, mit primesieve wurden 50.000.000 Primzahlen berechnet, mit isprime 5.000.000, die Werte in der Tabelle entsprechen der Laufzeit in Sekunden. Die Ergebnisse liegen dabei erstaunlich dicht zusammen. Moderne JIT Compiler sind also bei solchen einfachen Benchmarks den Herkömmlichen Compilern mindestens ebenbürtig.

primesieve isprime
java 5,598 10,846
c# 5,628 11,436
gcc 5,650 11,436
gcj 5,729 11,175

Quellcode

Hier der Quellcode der Java Version, die anderen Version sind nahezu identisch.

public class PrimeSieve {
    public static final int SIZE  = 50000000;
    public static final int SIZE2 = 5000000;

    public static boolean isprime(int n) {
        if (n < 2) {
            return false;
        }
        else if (n == 2) {
            return true;
        }
        else if (n % 2 == 0) {
            return false;
        }
        else {
            for (int i=3; i*i<=n; i+=2) {
                if (n%i==0) {
                    return false;
                }
            }
            return true;
        }
    }

    public static void primesieve(boolean[] arr) {
        int len = arr.length;

        java.util.Arrays.fill(arr, true);

        if (len > 0) arr[0] = false;
        if (len > 1) arr[1] = false;

        for (int i=4; i<len; i+=2) {
            arr[i] = false;
        }

        for (int i=3; i*i<=len; i+=2) {
            if (arr[i]) {
                for (int j=i<<1; j<len; j+=i) {
                    arr[j] = false;
                }
            }
        }
    }

    public static void main(String[] args) {
        boolean[] arr;
        long t1,t2;

        // warm up and test
        arr = new boolean[10000];
        primesieve(arr);
        for (int i=0; i<10000; i++) {
            if (isprime(i) != arr[i]) {
                throw new RuntimeException("Error in primesieve/isprime at " + i);
            }
        }

        // benchmark primesieve
        arr = new boolean[SIZE];
        t1 = System.currentTimeMillis();
        primesieve(arr);
        t2 = System.currentTimeMillis();

        System.out.println((double)(t2-t1)/1000.0);

        // benchmark isprime
        t1 = System.currentTimeMillis();
        for (int i=0; i<SIZE2; i++) {
            boolean b = isprime(i);
        }
        t2 = System.currentTimeMillis();

        System.out.println((double)(t2-t1)/1000.0);
    }
}