Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Just for the sake of comparison, I ran your groovy code vs a similarly styled ruby version of fib.

Groovy 2.0.1 (simply ran with 'groovy fib.groovy') JVM 1.7.0_06_64-b24 ~520ms

Ruby 1.9.3p194 ~475ms

Obviously this is well into micro-benchmark territory but it seems even worse case is on the order of ruby's performance which is perfectly acceptable for a large number of tasks.



Is that the @compilestatic one with 520ms ?! I'd imagine not.

Certainly Ruby's acceptable for a large number of tasks, as is Groovy. I use it every day, and will enjoy the speed benefits of Groovy2 in Grails2.x in the coming months, but it's certainly production ready for a large number of tasks now.

As many people continue to point out, if Groovy's slow, write those portions in pure Java. But you can get a lot of the way there just by using explicit types when you know them. The @CompileStatic is yet another performance boost, but you can often get improved Groovy perf by typing if you want to.


520ms was for the full dynamic version.

But we did have a snafu. The 'groovy' program seems to choose its JVM in an odd way, it was using Apple's 1.6 JVM despite 'java -version' returning the 1.7 JVM.

I fixed this by setting JAVA_HOME and now get ~300ms for the full dynamic version, 22ms for explicit types and 586ms for the @CompileStatic version.

I'm guessing my method of running this is not compatible with @CompileStatic given its results. Did you run this through groovyc and package it into a jar for your tests?

This is on a 2012 MBA with the i5 cpu btw.


I actually ran through the intellij version 12 EAP "LEDA" which has Groovy 2 in it for most of the tests.

The @compilestatic stuff should work regardless, but you do need to import the compilestatic transform.

import groovy.transform.CompileStatic


Well I ran it in IntelliJ and saw the same results. Then I found the problem...

I used compile_static3.groovy from your repo for the test which contains the following:

  bench(d, "fib_dynamic", 30, "Full dynamic ")
  bench(d, "fib_integer", 30, "Groovy w/ explicit types")
  bench(d, "fib", 40, "Explicit type w/@CompileStatic")
Notice the '40' on the last line :p

Corrected results:

  Full dynamic  took 305 ms
  Groovy w/ explicit types took 22 ms
  Explicit type w/@CompileStatic took 7 ms
Which is much more like what I expected compared to Ruby at 475ms.


But.... this was in my verbal presentation - move that @compilestatic benchmark to the first test - it'll be different. There's something about running it after the other two which is adding to the benefit - caching maybe? Moving it to the first one gives me 18-20ms generally. Try it :)


Just a guess but the JIT may be detecting the recursion and replacing it with a loop. The recursion signature is the same for each method so the JIT may be able to catch that.

Letting the JIT warm up is enlightening though, I looped the 3 tests 1000 times and also looped my ruby test 1000 times and I get this:

  Explicit type w/@CompileStatic took 5 ms
  Groovy w/ explicit types took 11 ms
  Full dynamic  took 75 ms

  Ruby took 464ms


Very interesting - haven't compared it to Ruby, but the 75ms was interesting on its own. I knew dynamically Groovy would generally be faster than Ruby, but not by that much, given the runtime dynamism.

Thanks! (and thanks for the pull request fix)




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: