Comparison of Java, Python and Ruby

What is the best programming language? This is one of the most popular question for anyone who are going to study new language. I also used to ask myself the same question. As a consequence, it is a kind of a war. The latest thread regarding this question was the hard fight and its copy at Blognone. The truth behind the scene is that you must not expect to get any fairness out of any comparison. There are so many criteria and assumptions which might help some languages. However, it is still worth to try.

This comparison performed 5 classes of all 3 languages; console, hash, io, list and math. Actually, they were done twice. The first run was performed by the author and the second run was optimized and run again by me.

Console

This test aims to compare the performance of I/O to console. In other words, it is actually the performance of print function. However, there is another factor as far as I know. It is about the loop. I'm not sure about Ruby but Java has no overhead at this point and Python has a lot of overhead due to range(). So I changed range() to xrange() as follow and it was a little bit faster.

for i in xrange(1000000):
    print i

Hash

Python and Ruby have built-in hash-like dictionary. In Java, we have so many options but this test chose HashMap. The HashMap will be increased size automatically just like in Python and Ruby. As a result, Python was much faster than Java.

public class test {
  public static void main([] args) {
    for (int i = 0; i < 6000; i++) {
       x = new ();
      for (int j = 0; j < 1000; j++) {
         I=new (i);
         J=new (j);
        x.put(J,I);
        x.get(J);
      }
    }
  }
}

If you are in Java fanclub, please be patience. Above code might look unfair in term of HashMap usage. It is fair as long as the assumption is to compare HashMap and dict in Python in the same behavior. In contrast, dict in Python will be increased size automatically too. Above code could be optimized to get faster speed due to the overhead of increasing hash size as follow. As a result, Java was now the fastest.

import java.util.*;
 
public class hash {
    public static void main([] args) {
        for(int i=0;i<6000;i++) {
             x = new (1000);
            for(int j=0;j<1000;j++) {
                x.put(j,i);
                x.get(j);
            }
        }
    }
}

IO

In addition to the speed of print to console, this experiment aims to focus on print to file object. I have never understood how to use file object in Java. However, below is the optimized code and again it was the fastest.

import java.io.*;
 
public class io {
    public static void main([] args) throws  {
         writer = new (new ("/tmp/scratch"));
        for(int i=0;i<1000000;i++) {
            writer.write(i);
        }
        writer.close();
    }
}

List

Dynamic list in Python and Ruby seems to be implemented by array so increasing size automatically might not perfect due to some overhead of copying data. This problem is also applied to Java like above Hash so it could be optimized too.

import java.util.*;
 
public class list {
    public static void main([] args) {
        for(int i=0;i<3000;i++) {
             v = new (1007);
            v.add("a");
            v.add("b");
            v.add("c");
            v.add("d");
            v.add("e");
            v.add("f");
            v.add("g");
            for(int j=0;j<1000;j++) {
                v.add(j);
                v.get(j);
            }
        }
    }
}

Again and again. The optimized java code was the fastest because of no more increasing size.

Math

The original Python code relied on Numpy. It is not fair at all so I will use below code instead.

import math
x = [0]*200000
gauss = [0]*200000
laplace = [0]*200000
si = [0]*200000
sisqr = [0]*200000
bp = [0]*200000
for i in xrange(200000):
    x[i] = i/10000.0-40.0
    gauss[i] = math.exp(-1.0*x[i]*x[i])
    laplace[i] = math.exp(-1.0*math.fabs(x[i]))
    si[i] = math.sin(x[i]*math.pi)/x[i]*math.pi
    sisqr[i] = si[i]*si[i]
    bp[i] = si[i]*math.cos(x[i]*100)

Again, Java is the fastest. I can't imagine how to optimize Python to run faster than Java without helping from extension library like C. Below are the result time measured on my laptop.

elapsed

              java     python       ruby
console      2.369      1.129      2.423
hash         1.360      3.696      9.005
io           0.141      1.866      4.243
list         0.239      1.829      3.558
math         0.249      1.957      3.108

maxsize

              java     python       ruby
console    254.492      8.422      3.293
hash       254.492      8.418     13.730
io         248.734      8.422      3.285
list       249.238      8.418      5.738
math       284.723     29.258     56.699

maxrss

              java     python       ruby
console     10.102      5.639      1.680
hash        10.148      5.680     12.133
io           5.465      5.633      1.664
list         5.527      5.637      4.141
math         4.621     26.582     53.918

Lastly, I tried to compile python prior to the running to eliminate compiling time during startup.

              java     python       ruby
console      2.481      1.028      2.402
hash         1.417      2.042      8.997
io           0.141      1.716      4.228
list         0.241      1.267      3.549
math         0.248      1.511      3.035

However, one thing I learn from this comparison is that every pieces of Python are well optimized and Python might work perfectly on almost circumstances as long as the application heavily depends on algorithm. If you would like to get the top class performance by tuning data structure, you should use static type like Java or C instead.

Note that you may get the complete code at http://www.blognone.com/node/4385.

Tags: , , , ,

Post new comment