1

I'm working on groovy code perfomance optimization. I've used jvisualvm to connect to running applicaton and gather CPU samples. Samples say that org.codehaus.groovy.reflection.CachedMethod.inkove takes the most CPU time. I don't see any other application methods in samples.

What is the right way to dig into CachedMethod.invoke and understand what code lines really give perfomance penalties?

Thanks.

UPD: I do use Indy, it didn't help me.

I didn't try to introduce @CompileStatic since I want to find my bottlenecks before rewriting groovy to java.

My problem a bit similar to this thread: Call site caching faster than invokedynamic?

I have a code that dynamically composes groovy script. Script template looks this way:

def evaluateExpression(Map context){
    def user = context.user
    %s
}

where %s replaced with

user.attr1 == '1' || user.attr2 == '2' || user.attr3 = '3'

There is a set (20 in total) of replacements have taken from Databases. The code gets replacements from DB, creates GroovyScript and evaluates it. I suppose the bottleneck is in the script execution. What is the right way to fix it?

Capacytron
  • 3,425
  • 6
  • 47
  • 80
  • Are you using the *Indy* artifact ? – Nicholas Apr 10 '16 at 13:46
  • Hi, did replace default groovy with *Indy* after submitting the question. Can't say it helped a lot according to newrelic metrics. Now top CPU consumer is **org.codehaus.groovy.vmplugin.v7.Selector$MethodSelector.doCallSiteTargetSet** I assume I did succeed in switching to InvokeDynamic. What should I do with *Selector$MethodSelector.doCallSiteTargetSet* now :) ? – Capacytron Apr 10 '16 at 14:48
  • How about *@CompileStatic* ? – Nicholas Apr 10 '16 at 15:10
  • I would like to avoid randomly rewriting code to make it *@CompileStatic*. I would like to find bottleneck before doing something serious... – Capacytron Apr 10 '16 at 15:16

1 Answers1

0

So, I've tried various things

  1. groovy-indy, doesn't work
  2. groovy-indy with some code "optimization", doesn't work. BTW, I'started to play around with try/catch and it as a result I made my "hotspot" run 4 times faster. I'm not good at JVM internals, but internet says - try/catch prevents optimizations. I assumed it as a ground truth. Need to g deeper to understand who it really works.
  3. I gave up, turned off invokedynamic and rewrote my "hottest" code with @CompileStatic. It took about 3-4 hours and I my code runs 100 time faster now.

Here are initial metrics with "invokedynamic support"

count = 83043

     mean rate = 395.52 calls/second

 1-minute rate = 555.30 calls/second

 5-minute rate = 217.78 calls/second

15-minute rate = 82.92 calls/second

           min = 0.29 milliseconds

           max = 12.98 milliseconds

          mean = 1.59 milliseconds

        stddev = 1.08 milliseconds

        median = 1.39 milliseconds

          75% <= 2.46 milliseconds

          95% <= 3.14 milliseconds

          98% <= 3.44 milliseconds

          99% <= 3.76 milliseconds

        99.9% <= 12.19 milliseconds

Here are @CompileStatic metrics with ind turned off. BTW, there is no reason to use @CompileStatic if "indy" is turned on.

 count = 139724

     mean rate = 8950.43 calls/second

 1-minute rate = 2011.54 calls/second

 5-minute rate = 426.96 calls/second

15-minute rate = 143.76 calls/second

           min = 0.02 milliseconds

           max = 24.18 milliseconds

          mean = 0.08 milliseconds

        stddev = 0.72 milliseconds

        median = 0.06 milliseconds

          75% <= 0.08 milliseconds

          95% <= 0.11 milliseconds

          98% <= 0.15 milliseconds

          99% <= 0.20 milliseconds

        99.9% <= 1.27 milliseconds
Capacytron
  • 3,425
  • 6
  • 47
  • 80