Статьи

Сравнение производительности Java 7 и Groovy 2.1

Я не использовал Groovy в течение 2 лет, с момента моего последнего контакта с Grails . Я застрял в (жестком) ядре Enterprise Java с некоторыми аспектами производительности в фоновом режиме. Я почти упустил шанс изучить Спока , но, к счастью, варшавская Java User Group помогла мне избавиться от некоторых устаревших систем и вернуться к нормальному саморазвитию. На самом деле, я надеюсь, что такие фреймворки, как Spock или Geb , изменят подход к написанию тестов, сделав их проще и эффективнее. Обе платформы используют Groovy, а также новый король в инструментах сборки — Gradle . Наблюдая за тем, как Groovy влияет на нашу повседневную работу, я решил посмотреть на его производительность и сравнить его с Java 7.

Моя тестовая среда основана на Java 1.7.0_25 и Groovy 2.1.6. Как всегда в таких сравнениях, я использовал Caliper в версии 1.0-бета-1 (почти стабильной) и подготовил ряд (я надеюсь) репрезентативных микробенчмарков.

Первый бенчмарк, основанный на фреймворке Fork / Join, должен быть максимально похож на обоих языках, потому что он использует некоторые нативные механизмы. Мой тест инициализирует массив некоторыми случайными данными типа int, а затем использует framework для поиска самого большого элемента в массиве. В Groovy мои вычислительные функции выглядят так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
@Override
Integer compute() {
  def size = end - start
  if (size == 1) {
    Math.max(array[start], array[end])
  } else {
    int diff = size / 2
    MaxValueSeeker left =
      new MaxValueSeeker(array, start, start + diff)
    left.fork()
    MaxValueSeeker right =
      new MaxValueSeeker(array, start + diff, end)
    Math.max(right.compute(), left.join())
  }
}

Java-версия, конечно, очень похожа. После дюжины минут измерения я получаю очень многообещающий результат: Groovy медленнее всего… в 8 раз.

Теперь пришло время проверить некоторые более реалистичные в повседневной разработке. Я выбрал простой POJO / POGO (да) с несколькими простыми операциями, просто чтобы быть уверенным, что JIT не устранит мой код (и поверьте мне, он любит делать такие шутки). Мой метод псевдо «бизнес-логики» в Groovy:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
def int proceed(int reps) {
  List<GroovyPojo> list = new ArrayList<>()
  int sum = 0;
  reps.times {
    // first param is int and second is String
    list.add(new GroovyPojo(value: it, stringValue: it))
  }
  list.each {
    if (Integer.parseInt(it.stringValue) == it.value) {
      sum += it.value
    }
  }
  sum
}

Версия Java отличается в основном геттерами и ручным боксом строк в конструкторе POJO. Еще один раз дюжина минут, потраченных на чтение новостей, и … на этот раз Groovy медленнее всего в 7 раз

Последний тест должен быть стрессовым и проверять оба языка в более сложных вычислениях. Я решил и выбрал алгоритм быстрой сортировки. Несколько циклов, несколько операторов if должны работать. Я не собираюсь копировать и вставлять это здесь, потому что это хорошо известное решение. Стоит упомянуть, конечно же, временные результаты, превосходящие Groovy почти в 5 раз! Но я немного погуглил и заметил, что Groovy 2.0 представил аннотацию @CompileStatic, которая должна дать нам дополнительное повышение производительности. Итак, давайте проверим … Да, при статической компиляции преимущество Java упало до 220%.

В таблице ниже вы можете найти подробные результаты. Подводя итог — я не уверен, что использование Groovy в критически важных функциях — хорошая идея, но определенно это отличное решение для реализации тестов, создания прототипов и т. Д. Просто позвольте мне подчеркнуть, что написание анализатора результатов Caliper заняло около 6 строк в Groovy. (анализ json, итерация по измерениям и подсчет среднего)

Сравнение производительности

метод Java [ns] Groovy [нс] фактор
Вилка / Регистрация 22,132 181,018 8,18
Pojos 117,914 856,337 7,26
Quicksort 68,728 330,159 4,80
Быстрая сортировка с @CompileStatic 67,752 147,792 2,18

Ссылка: Java 7 против Groovy 2.1 Сравнение производительности от нашего партнера JCG Якуба Кубрински в блоге Java (B) Log .