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.

6 comments:

  1. Check this again with @CompileStatic in Groovy2. I've done some basic Fib testing between iterations of Groovy - full dynamic (wih 'def' and no type delcaration, type declarations, and @CompileStatic) .

    Results were:

    Totally dynamic way took 11173 ms
    Groovy using explicit types took 1250 ms
    Explicit types and @CompileStatic took 492 ms

    Huge diffs - give it another look and compare against Scala please.

    ReplyDelete
    Replies
    1. Ahh... I saw your other post: http://blog.evan-wong.com/2012/07/java-vs-groovy20-vs-scala-simple.html

      In my own comparisons, recursive Java fib was still faster, by about 50%. With my examples above, my java fib with 40 iterations, as the others, took 315ms, compared to the 492ms above.

      Delete
    2. Thanks for you input!

      um.. in theory, I think if the groovy code is compiled statically, it should just be byte code very similar to the Java code which should has similar performance. Did you also run some compiler warm up to make sure the test fairer?

      And actually, I don't think using explicitly type vs dynamic type will make a performance different without the @CompileStatic annotation.
      http://groovy.codehaus.org/Runtime+vs+Compile+time%2C+Static+vs+Dynamic
      "it actually takes longer if you provide lots of static type information."
      This was since groovy 1.1. They haven't updated it so I assume it is still true.
      Are you running Java7? that can be because of the new invokeDynamic feature.

      Delete
  2. I have read your blog its very attractive and impressive. I like it your blog.

    Java Training in Chennai Core Java Training in Chennai Core Java Training in Chennai

    Java Online Training Java Online Training Core Java 8 Training in Chennai Core java 8 online training JavaEE Training in Chennai Java EE Training in Chennai

    ReplyDelete
  3. Nice blog & thanks for the share.

    Checkout http://skartecedu.in for the best digital marketing training in Chennai.

    ReplyDelete