Оптимизация производительности Groovy

Я работаю над оптимизацией производительности groovy кода. Я использовал jvisualvm для подключения к работающему приложению и сбора образцов ЦП. В примерах говорится, что org.codehaus.groovy.reflection.CachedMethod.inkove занимает больше всего процессорного времени. Я не вижу других способов применения в примерах.

Как правильно изучить CachedMethod.invoke и понять, какие строки кода действительно снижают производительность?

Спасибо.

UPD: я использую Indy, мне это не помогло.

Я не пытался представить @CompileStatic, так как хочу найти свои узкие места, прежде чем переписывать groovy на java.

Моя проблема немного похожа на эту тему: Вызвать кеширование сайта быстрее, чем invokedynamic?

У меня есть код, который динамически составляет скрипт groovy. Шаблон скрипта выглядит так:

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

где %s заменено на

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

Существует набор (всего 20) замен, взятых из баз данных. Код получает замены из БД, создает GroovyScript и оценивает его. Я предполагаю, что узкое место находится в выполнении скрипта. Каков правильный способ исправить это?


person Capacytron    schedule 09.04.2016    source источник
comment
Вы используете артефакт Indy?   -  person Nicholas    schedule 10.04.2016
comment
Привет, заменил groovy по умолчанию на Indy после отправки вопроса. Не могу сказать, что это сильно помогло, согласно метрикам newrelic. Теперь основным потребителем ЦП является org.codehaus.groovy.vmplugin.v7.Selector$MethodSelector.doCallSiteTargetSet. Я предполагаю, что мне удалось переключиться на InvokeDynamic. Что мне теперь делать с Selector$MethodSelector.doCallSiteTargetSet :)?   -  person Capacytron    schedule 10.04.2016
comment
Как насчет @CompileStatic?   -  person Nicholas    schedule 10.04.2016
comment
Я хотел бы избежать случайного переписывания кода, чтобы сделать его @CompileStatic. Я хотел бы найти узкое место, прежде чем делать что-то серьезное...   -  person Capacytron    schedule 10.04.2016


Ответы (1)


Итак, я пробовал разные вещи

  1. заводной инди, не работает
  2. groovy-indy с некоторой «оптимизацией» кода не работает. Кстати, я начал экспериментировать с try/catch, и в результате моя «горячая точка» работала в 4 раза быстрее. Я плохо разбираюсь во внутренностях JVM, но интернет говорит - try/catch предотвращает оптимизацию. Я принял это за непреложную истину. Нужно копнуть глубже, чтобы понять, кто на самом деле работает.
  3. Я сдался, отключил invokedynamic и переписал свой «горячий» код с помощью @CompileStatic. Это заняло около 3-4 часов, и теперь мой код работает в 100 раз быстрее.

Вот начальные метрики с «вызовом динамической поддержки»

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

Вот метрики @CompileStatic с отключенным ind. Кстати, нет причин использовать @CompileStatic, если включен «indy».

 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
person Capacytron    schedule 18.04.2016