text: Groovy++ in action: how to make $5000 in one hour
  There are two dimensions of this slowness. First of all being fully dynamic language Groovy makes every method invocation (and any operation in reality) dispached dynamicly. It means we need to check what is the class of an instance, to find meta class, to see types of parameters, to find method most specific for these parameters and finally make invocation itself. BTW, the invocation itself can also involve some on-the-fly code generation. The second dimension is somehow derived from the first one. In mult-threaded environment some of this checks requires volatile reads/writes (for each method call etc.), which slows things down noticeably.
  Of course Groovy Core team, which I have honor to belong to, does everything possible to speed things up. We did very speed-up serious job in Groovy 1.5 & 1.6, which was a bit improved in 1.7, and right now extremely promising development going on in Groovy 1.8 brunch (beta4 was released just few days ago).
  Nevertheless, as of today Groovy can not compete with Java in performance. My expirience with Groovy 1.7.x is that it is 4 to 10 times slower than Java code. You can try project, which runs the same benchmarks against Groovy 1.7/1.8, Java and Groovy++.
  The situation is really pity - we have buitiful general purpose language, which is slow only because dynamic dispatch - extremely important feature but very specific one - requires it.
  Of course, you know that solution exists. It is called Groovy++ - statically typed extension of Groovy. You can find more information at Groovy++ project page To make really long story short Groovy++ allows you to annotate piece of code (class, method or whole module) being statically or dynamically compiled (there is also mixed mode where compiler allows to mix static and dynamic calls together). Such approach gives you best of the both worlds - performance where it is important and dynamic features where you need it.
  My personal expirience with Groovy++ is pretty simple - approximately 80% of Groovy code can be made statically typed with zero or minimal efforts. Thanks to extremely powerful type inference implemented in Groovy++. Saying the same thing in other words - 80% of Groovy code can be speed up 4 to 10 times with zero or minimal effort. BTW, the only required effort usually is adding type to dome method parameter or local variable, the rest usually happens magically.
  I want to show you one example of such benchmark, which I was using recently to prove to my collegue that using of regular Groovy for multi-threaded application is not so good idea.
  class LockPerf {
  public static void main(String[] args) {
  def processors = Runtime.runtime.availableProcessors()
  for(def threadNum = 1; threadNum <= 1024; threadNum = threadNum < 2*processors ? threadNum+1 : threadNum*2) {
  def counter = new AtomicInteger ()
  def cdl = new CountDownLatch(threadNum)
  def lock = new ReentrantLock()
  def start = System.currentTimeMillis()
  for(i in 0..<threadNum) {
  Thread.start {
  for(;;) {
  lock.lock()
  try {
  if(counter.get() == 100000000) {
  cdl.countDown()
  break
  }
  else {
  counter.incrementAndGet()
  }
  }
  finally {
  lock.unlock()
  }
  }
  }
  }
  cdl.await()
  println "$threadNum ${System.currentTimeMillis() - start}"
  }
  }
  }
  What does this benchmark do?
  Pretty much nothing.
  We can think about this benchmark as emulation of synchronization logic in complex muti-threaded algorithm and what we try to evaluate is how much overhead we bring by using Groovy instead of Java/Scala/Groovy++We can think about this benchmark as emulation of synchronization logic in complex muti-threaded algorithm and what we try to evaluate is how much overhead we bring by using Groovy instead of Java/Scala/Groovy++
  - It iterates over some sequence of numbers (from one to double number of cores and then double it till 1024)
  - For each such number it starts concurrent threads
  - Each thread competes for shared lock
  - When lock aquired it increment shared atomic value and release the lock
  - If shared counter reaches 100000000 the thread stops
  - When all threads stopped the iteration of benchmark is completed and "$threadNum $iterationElapsedTimeInMillis" printed
  Just for completeness here is Java code implementing the same benchmark. I can not miss the opportunity to notice that it is more verbose than Groovy.
  public class LockPerf {
  public static void main(String[] args) {
  int processors = Runtime.getRuntime().availableProcessors();
  for (int threadNum = 1; threadNum <= 1024; threadNum = threadNum < 2 * processors ? threadNum + 1 : threadNum * 2) {
  final AtomicInteger counter = new AtomicInteger();
  final CountDownLatch cdl = new CountDownLatch(threadNum);
  final ReentrantLock lock = new ReentrantLock();
  long start = System.currentTimeMillis();
  for (int i = 0; i < threadNum; ++i) {
  new Thread(new Runnable() {
  public void run() {
  for (;;) {
  lock.lock();
  try {
  if (counter.get() == 100000000) {
  cdl.countDown();
  break;
  } else {
  counter.incrementAndGet();
  }
  } finally {
  lock.unlock();
  }
  }
  }
  }).start();
  }
  try {
  cdl.await();
  } catch (InterruptedException e) {//
  }
  System.out.println(threadNum + " " + (System.currentTimeMillis() - start));
  }
  }
  }
  You probably want to ask me what about Groovy++ code. It is interesting (and I am not tricking you) that the only change needed in original Grovy code was to add @Typed annotation to the class
  @Typed
  class LockPerf {
  // all the rest is exactly as above
  }
  Here are benchmark's results on 4-core MacBook Pro
  What can we notice in benchmark results
  - Groovy versions are more than 6 times slower than Java
  - Java and Groovy++ competes very strongly (which is correct as theoretically both should perform equally)
  - Groovy 1.8 is a bit slower than 1.7 (which is fair for unreleased yet version)
  My conclusion is obvious and predictable - use Groovy and extend it's power with Groovy++ where needed. It will make your code stronger and faster.
  Hope you enjoyed it and till next time!
  Ah, I promised to tell you about $5000 in one hour
  Usually I don't do consulting. But sometimes you have challenge or an offer you can not reject.
  Last week I was in Russia and old friend approached me with very urgent problem - they have important milestone and customer presentation of new version for big Grails application and one of most important new reports took more than seven seconds (totally unacceptable) to generate (mostly because of wrong database design done on earlier stages, which required to do a lot of data aggregation on application level). He knew that performance is my hobby and asked if I can help.
  I said "you know what - I can seat with you for few hours and let us see what can we do. If we have great result you pay well if not we had fun together and you earn me good dinner" That was the deal and truly speaking I did not expect much. My plan was to review algorithms and see what can be optimized or targeted to be rewritten in Java.
  The problematic code was more than 3000 lines of Groovy code splitted in 12 classes. Fortunately, well separated from report generation logic and reasonably covered with tests (in my opinion the only way to go with any code especially non-statically typed).
  It became very clear that it is not possible for me to understand what's going on in short time, so I used simple trick - tried to apply Groovy++ (meaning installed Groovy++ Grails plugin and put @Typed here and there).
  THAT WAS AMASING!
  We had exactly 10 compilation errors:.
  - 3 errors were fixed by adding type to method parameter
  - 2 errors were fixed by setting correct generic type to collection
  - 1 was about setting correct type of local variable
  - 2 was real dynamic code required mixed mode of compilation
  - and the rest 2 was absolute bugs in uncovered code, which static compiler helped us to find
  What was even more important is that two pieces of really dynamic code we discovered was really strange. Two components were communicating between each other by generating and storing large intermediate XML document in database. As nobody could explain why is it done this way we simply replaced all this XML generation, storing, loading and parsing with direct in memory call and 2.5 seconds became 1.2 seconds All that took another 40 minutes (mostly spent in smoking area in philosiphical discussion about programmers and idiots).
  The last 0.3 seconds was caught by my local friend who noticed in one compiler error that part of calculation unnecessary done in BigDecimals instead of doubles because of use of 1.0 notation instead of 1.0d Here I have huge feature request for Groovy++ to have reasonable warnings in such cases. BTW, I must admit that during the exercise we had one NPE crash of Groovy++ compiler, which fortunately was easy to fix.
  That's it. In a bit less than hour and a half we (myself and two local guys) managed to speed up critical part of application from unacceptable to required performance using Groovy++, IntelliJ IDEA and a bit of common sense. What is important here is that going to Java was not an option due time constraints.
  I must tell you it was one of the best paid hour and a half in my life :)
  I must also mention that yesterday my friends wrote me that they made presentation successfully and got approval from customer for continuation of the project till the end of the year.
  Andy Leung replied on Tue, 2011/02/08 - 1:14pm
  After investigation, it was due to massive StringBuffer was used with possible memory leak. So I just simply used find and replace to change all of them to StringBuilder since it wasn't a multi-threaded application, and properly released all memory. Entire optimization took less than 15 mins and the application complete processing within 2 seconds in total and memory consumption was at peak of 2MB instead of original 64MB. So that was about 26x faster but in this case, it was just because of the Senior Developer's skill problem, it's not really about Java.
  Alex Tkachman replied on Tue, 2011/02/08 - 1:30pm
  in response to:
  Andy Leung
  Andy Leung replied on Tue, 2011/02/08 - 3:22pm
  in response to:
  Alex Tkachman
  Dudu Zerah replied on Tue, 2011/02/08 - 3:24pm
  Hontvári József... replied on Tue, 2011/02/08 - 9:22pm
  Alex Tkachman replied on Wed, 2011/02/09 - 3:01am
  in response to:
  Hontvári József Levente
  Artur Biesiadowski replied on Wed, 2011/02/09 - 9:49am
  Please make sure you are using server compiler for testing and that you warm up the benchmarks properly before taking measurements. In other case, you are skewing numbers (probably in groovy favor), as java inlining/etc is not able to fully kick in.
  Loren Kratzke replied on Wed, 2011/02/09 - 5:46pm
  in response to:
  Hontvári József Levente
  madhusudana replied on Thu, 2011/02/10 - 3:33am
  Alex Tkachman replied on Thu, 2011/02/10 - 11:01am
  in response to:
  madhusudana
  diego Visentin replied on Tue, 2011/02/15 - 5:33am