Tuesday, July 10, 2012

Java vs Groovy2.0 vs Scala Simple Performance Test

Since Groovy2.0 is out, I want to re-test the performance difference between Java, Groovy2.0 and Scala. The previous tests: Part 1 and Part 2

The machine and the code are the same as the previous tests. The only thing change is that I am using groovy2.0. To make it the results more clear, I am only including the results for f(30) and f(50):

n implementation result Java Groovy2 Groovy2 @CompileStatic Scala
30 for-loop 832040 0 (ms) 0 (ms) 1 (ms) 0 (ms)
30 recursive 832040 19 (ms) 66 (ms) 20 (ms) 20 (ms)
50 for-loop 12586269025 0 (ms) 0 (ms) 0 (ms) 0 (ms)
50 recursive 12586269025 182462 (ms) 356920 (ms) 176468 (ms) 180898 (ms)


I split the Groovy test to two. One with the new annotation @CompileStatic (I put it in the class level) and one without. The one without is suppose to use the JDK7 new feature invokeDynamic which should give some performance gain but unfortunately JDK7 is not supported in Mac Snow Leopard. @CompileStatic is a new feature that give performance gain to groovy code with type safety check where dynamic features are not required. More information here.

The results show that the big performance gain by adding the @CompileStatic which is making Groovy up to par with Java and Scala. The common ways for Groovy developers to solve performance's problem is to write that piece of code in Java. Now with this new @CompileStatic, everything can be just in Groovy. And the ideal case is that if the JDK7 invokeDynamic gives Groovy2 the same performance as Java, then the @CompileStatic is not needed at all (if you want type safe, you can just use another new annotation @TypeChecked).

Friday, April 6, 2012

Java vs Groovy vs Scala Simple Performance Test - 2

As my previous post showed, the performance of Scala was as good as Java but Groovy was obviously slower than both of them while running the Fibonacci number test and the Fibonacci number calculation was done in the recursive way.
Now let's try to revise the implementation to the for loop calculation and see their performance again.

Java
    public long fib(long n) {
        long result = 0;
        long[] prevResult = new long[]{0, 1};
        for (int i = 2; i <= n; i++) {
            result = prevResult[0] + prevResult[1];
            prevResult[0] = prevResult[1];
            prevResult[1] = result;
        }
        return result;
    }
Groovy
    def long fib(long n) {
        def result = 0
        def prevResult = [0L, 1L]
        for (int i = 2; i <= n; i++) {
            result = prevResult[0] + prevResult[1]
            prevResult[0] = prevResult[1]
            prevResult[1] = result
        }
        return result
    }
Scala
  def fib(n: Long): Long = {
    var result = 0L
    val prevResult = Array(0L, 1L)
    for (i <- 2L to n) {
      result = prevResult(0) + prevResult(1)
      prevResult(0) = prevResult(1)
      prevResult(1) = result
    }
    return result
  }

Results:
n implementation result Java Groovy Scala
10 for-loop 55 0 (ms) 1 (ms) 0 (ms)
10 recursive 55 0 (ms) 8 (ms) 13 (ms)
30 for-loop 832040 0 (ms) 1 (ms) 0 (ms)
30 recursive 832040 14 (ms) 59 (ms) 14 (ms)
50 for-loop 12586269025 0 (ms) 0 (ms) 1 (ms)
50 recursive 12586269025 153909 (ms) 285553 (ms) 156361 (ms)
100 for-loop 3736710778780434371 0 (ms) 1 (ms) 2 (ms)
500 for-loop 2171430676560690477 0 (ms) 7 (ms) 9 (ms)

I highlighted the previous test results to compare this ones.

No suprise, the for-loop boost the performance for all of them.

While n=50, Java and Scala took about 150sec and Groovy took about 285sec in the previous recursive tests. With the for-loop implementation, they all took less than 1ms. Even while running the for-loop with n=100 and n=500, the calculation time was still amazingly fast.
This can be explained by the time complexity where the recursive implementation is O(2^n) and the for-loop one is just O(n). This also demonstrates why using the right algorithm is so important.

An interesting observation was that while the calculation is taking very short time, Groovy was actually faster than Scala by a little bit. I am not sure why but it should be save to ignore the 1/2ms difference.

Base on all the results, Java was always the fastest and Scala outperformed Groovy while taking long calculation. When Groovy2 and/or JDK7 is out in Mac, I will probably do the test again and see if Groovy will catch up with the performance.

Thursday, April 5, 2012

Java vs Groovy vs Scala Simple Performance Test

There are a lot of interesting discussions/comparions about the performance between these JVM languages. 
To see the real differences in action myself, I am writing some simple tests using the well-known Fibonacci number. 

My environment:
Mac OS X - Snow Leopard
Java 1.6.0_26
Groovy 1.8.6
Scala 2.9.1-1

I implemented the Fibonacci in the recursive way and before I started, I ran some loops to "warm up" the JVM first to make the results more reasonable.
Anyway, here are the implementations:

Java
    public long recursiveFib(long n) {
        if (n == 0) {
            return 0;
        } else if (n == 1) {
            return 1;
        }
        return recursiveFib(n - 1) + recursiveFib(n - 2);
    }
Groovy
    def long recursiveFib(long n) {
        if (n == 0) {
            return 0
        } else if (n == 1) {
            return 1
        }
        return recursiveFib(n - 1) + recursiveFib(n - 2)
    }
Scala
  def recursiveFib(n: Long): Long = {
    if (n == 0) {
      return 0
    } else if (n == 1) {
      return 1
    }
    return recursiveFib(n - 1) + recursiveFib(n - 2)
  }
n result Java Groovy Scala
10 55 0 (ms) 8 (ms) 13 (ms)
30 832040 14 (ms) 59 (ms) 14 (ms)
50 12586269025 153909 (ms) 285553 (ms) 156361 (ms)

From the above table, we can see that the differences increase as n increases. One interesting thing was that while running recursiveFib(10), Scala was the slowest one. Why? I am not very sure. Probably because of the JVM wasn't "warm up" enough or there were some internal Scala's stuffs going on. That's probably a separate topic to look at.
For recursiveFib(30), Groovy is like 4 times slower than Java and Scala but probably most human can't notice the difference between 14ms and 59ms.
However, when it comes to recursiveFib(50), even Groovy is just two-fold of Java and Scala, the difference is big as 150sec vs 285sec.
Overall, Scala's performance is almost as good as Java and this is probably because of the static compile time behavior of Scala while Groovy has a long way to catch up its performance with its dynamic nature.

How to improve the Groovy performance? We can run the performance bottleneck part in Java. This for sure can increase the performance overall. However, in some cases, we can actually improve the performance by just using a right solution. For this Fibonacci number, we can use for loop instead of this recursive implementation to boost the performance. I am going to test the differences again in the next blog.

Tuesday, January 31, 2012

Java Singleton - The Basics

There are number of ways to implement singleton in Java.
The very basic:
public class SingletonClass {
 
 private static final SingletonClass singleton;
 
 public static getSingletonInstance() {
  if (singleton == null) {
   singleton = new SingletonClass();
  }
  return singleton;
 }
}
However, using this way is not good if this is in a multi-threaded environment. The method should use the "synchronized" keyword to make it thread safe.
public static synchronized getSingletonInstance() {
 if (singleton == null) {
  singleton = new SingletonClass();
 }
 return singleton;
}
or
public static getSingletonInstance() {
 synchronized(SingletonClass.class) {
  if (singleton == null) {
   singleton = new SingletonClass();
  }
 }
 return singleton;
}
"synchronized" can be slowed because other threads will have to wait for it. It might not be a problem if only a few threads will be calling it at the same time. However, if there are a lot of threads trying to get the instance very frequently, then this should be a better approach:
public class SingletonClass {
 
 private static final SingletonClass singleton = new SingletonClass();
 public static getSingletonInstance() {
  return singleton;
 }
}
The shared instance is initialized in the static block so that there is no check in the method nor other threads need to wait for it. The drawback of this is that there is no lazy-load. The shared instance will be initialized even if the method is never called.
The thread-safe and lazy-load way from Bill Pugh:
public class SingletonClass {

        private SingletonClass() { 
  }
 
        private static class SingletonClassInstance { 
                public static final SingletonClassInstance instance = new SingletonClassInstance();
        }
 
        public static SingletonClass getInstance() {
                return SingletonClassInstance.instance;
        }
}
Thread-safe without the "synchronized" keyword and the instance is initialized on the first call. However, so far all of the above implementation needs to consider the serializable objects. If the fields of the singleton class are non-transient, attack can be done thru serializing and deserializing the SingletonClass.

Using enum to implement singleton base on Effective Java:
public enum SingletonClass {
 INSTANCE;
 
 public void doSomething() {
 }
}
Very clear implementation, guarantee against multiple instantiation, lazy-load, and no problem with the serializable objects like all of the above implementations. This should be so far the best way to implement Java singleton.

Monday, January 16, 2012

Putting code block in blogger posts - SyntaxHighlighter

Code block is important for writing technical blogs.

Since blogger doesn't have a default code block, I was trying to find a good way to put a code block for my posts.

I was first thinking to use the HTML5 <code></code> blocks and format them but I found the SyntaxHighlighter when I searched around. It is a self-contained javascript library for putting a nice formatted code blocks in webpages.

Here is how to do it in blogger:

1. Download or use the hosted version of SyntaxHighliger - I am using the hosted version since I don't want to host the files.

2. Go to the Templates setting in blogger and edit the template HTML. Right before the </head>, add:

  
  
  

3. The SyntaxHighligher comes with different kinds of brushes for different languages. Each brush type represent one type of programming lauguage block. I added the brushes using autoloader so that the page will only load the require script for the page instead of loading everything. When using the library in blogger, also need to set the bloggerMode as true. Following codes are added in the bottom of the template html (for my template, right below </macro:includable>):


4. Save Template. Now it is ready to use.

5. Start/Edit a post and switch to the HTML editor. To put a javascript code snipped:

function test() {
  //test
}

It will show up in the blog as:
function test() {
  //test
}

A list of brushes can be found here.