Subject:
C++ vs. Python vs. Perl vs. PHP performance benchmark
From:
Isaac Gouy
Date:
19.6.2012 г. 21:39 ч.
To:
Ivan Zahariev

Hi

The code I posted to your blog was garbled by the text box, so I've attached it to this email.

1) The ordinary Java translation of your Python program is SimplePrimes.java


In your Python implementation of the Sieve of Eratosthenes, there is never any change to the size of the array s -- the algorithm only requires a fixed size array, but Python doesn't provide a fixed size array. Java does provide a fixed size array and that is what every Java programmer would use to implement the Sieve of Eratosthenes.

In your Python implementation, there is a change to the size of the array res -- and the SimplePrimes.java program also uses a variable size array for res.



On my quad core machine your PrimeNumbersBenchmarkApp Java program showed --

real    0m8.983s
user    0m18.425s
sys    0m0.476s

On my quad core machine SimplePrimes.java showed --

real    0m3.156s
user    0m4.388s
sys    0m0.204s




2) The SimplePrimesWarmed.java program shows how performance increases after the JVM optimizes the program, and switches of interpreted to compiled code --


3.100350
2.293438
2.136179
2.188416
2.190429
2.196120
2.189274
2.112263
2.109705
2.110209

The same effect can be seen for your PrimeNumbersBenchmarkApp java program --

13.772833
5.338382
5.486536
5.566288
5.569079
5.554750
5.567980
5.554167
5.594199
5.649297



3) If you want to make Java look slow, then force your program to run using just interpreted code :-)

$ time java -server -Xint PrimeNumbersBenchmarkApp
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.
Found 664579 prime numbers.

real    1m50.003s
user    2m10.532s
sys    0m0.560s




4) Your blog post says -- "The benchmarks here do not try to be complete, as they are showing the performance of the languages in one aspect, and mainly: loops, arrays with numbers, basic math operations." -- but what is really being shown for your Java program is unnecessary Integer boxing/unboxing.


best wishes, Isaac

SimplePrimes.java

/* 
real	0m3.156s
user	0m4.388s
sys	0m0.204s
*/

import java.util.ArrayList;

public final class SimplePrimes
{
   static ArrayList<Integer> primes7(int n){
      ArrayList<Integer> res = new ArrayList<Integer>();
      if (n < 2) { return res; }
      res.add(2);
      if (n == 2) { return res; }

      // do only odd numbers starting at 3
      int[] s = n%2==0 ? new int[n/2 - 1] : new int[n/2];
      for (int i=3, j=0; i <= n; i+=2, j++) s[j] = i;

      int mroot = (int)Math.sqrt(n);
      int half = s.length;
      int i = 0;
      int m = 3;
      while (m <= mroot){
         if (s[i] != 0){
            int j = (m*m-3)/2; 
            s[j] = 0;
            while (j < half){
               s[j] = 0;
               j += m;
            }
         }
         i++; 
         m = 2*i+3;
      }      
      for (int j : s) if (j !=0) res.add(j);
      return res;
   }

   public static void main(String[] args){
      for (int i=0; i < 10; i++) 
         System.out.printf("Found %d prime numbers.\n", primes7(10000000).size());
   }
}

SimplePrimesWarmed.java

/* First 10 times (seconds)
3.100350
2.293438
2.136179
2.188416
2.190429
2.196120
2.189274
2.112263
2.109705
2.110209
*/

import java.util.ArrayList;

public final class SimplePrimesWarmed
{
   static ArrayList<Integer> primes7(int n){
      ArrayList<Integer> res = new ArrayList<Integer>();
      if (n < 2) { return res; }
      res.add(2);
      if (n == 2) { return res; }

      // do only odd numbers starting at 3
      int[] s = n%2==0 ? new int[n/2 - 1] : new int[n/2];
      for (int i=3, j=0; i <= n; i+=2, j++) s[j] = i;

      int mroot = (int)Math.sqrt(n);
      int half = s.length;
      int i = 0;
      int m = 3;
      while (m <= mroot){
         if (s[i] != 0){
            int j = (m*m-3)/2; 
            s[j] = 0;
            while (j < half){
               s[j] = 0;
               j += m;
            }
         }
         i++; 
         m = 2*i+3;
      }      
      for (int j : s) if (j !=0) res.add(j);
      return res;
   }

   public static void program_main(String[] args){
      for (int i=0; i < 10; i++) 
         System.out.printf("Found %d prime numbers.\n", primes7(10000000).size());
   }

   public static void main(String[] args){
      for (int i=0; i<66; ++i){ 
         System.gc(); 
         long t1 = System.nanoTime();
         SimplePrimesWarmed.program_main(args);
         long t2 = System.nanoTime();
         System.err.println( String.format( "%.6f", (t2 - t1) * 1e-9 ) );         
      }
   }
}

Attachments:
SimplePrimes.java1.1 KB
SimplePrimesWarmed.java1.5 KB