Рубрики
Без рубрики

Более мощный Groovy с потоками Java 8

Мой опыт использования потоков Java 8 в Groovy. Помечено как программирование, groovy, java, кодирование.

Подумайте о том, чтобы написать Groovy код для извлечения преобразованной версии элемента из заданной коллекции таким образом, чтобы преобразованная версия элемента удовлетворяла заданному предикату.

Вот фрагмент кода, предназначенный только для Groovy, который использует только функции Groovy.

(0..N).collect { e -> transform(e) }
      .findResult([]) { e -> predicate(e) ? e : null }

Вот фрагмент кода Groovy + Java, который использует потоки Java 8.

IntStream.range(0, N)
         .mapToObj { e -> transform(e) }
         .filter { e -> predicate(e) }
         .findAny()
         .orElse([])

В то время как первый фрагмент преобразует ( collect ) каждый элемент в исходной коллекции перед выполнением findResult (поэтапное выполнение), второй фрагмент выполняет весь конвейер функций для каждого элемента в исходной коллекции. Следовательно, фрагмент кода Groovy +Java более эффективен, поскольку он прекращает преобразование элементов, как только найдена преобразованная версия элемента.

С точки зрения параллелизма, вот фрагмент кода, предназначенный только для Groovy, распараллеленный с помощью GPars .

GParsPool.withPool {
    (0..N).collectParallel { e -> transform(e) }
          .findResult([]) { e -> predicate(e) ? e : null }
}

В то время как collect распараллелен (как collectParallel ), Findresult не распараллелен, поскольку он не поддерживается GPars. Кроме того, даже если FINDRESULT был распараллелен, он будет выполняться только после завершения collectParallel и, следовательно, наблюдаемая выше неэффективность из-за поэтапного выполнения все равно сохранится.

Для сравнения, вот распараллеленная версия фрагмента Groovy +Java.

IntStream.range(0, N)
         .parallel().
         .mapToObj { e -> transform(e) }
         .filter { e -> predicate(e) }
         .findAny()
         .orElse([])

В отличие от распараллеленного фрагмента кода, доступного только для Groovy, каждая функция в конвейере выполняется параллельно по мере того, как ее входные данные становятся доступными. Следовательно, это будет более эффективно, чем распараллеленный фрагмент только для Groovy.

Несколько лет назад Groovy сделал Java более совершенной. С потоками Java 8, я думаю, Java может сделать Groovy более совершенным.

Тем не менее, мне не терпится увидеть, как Groovy будет развиваться, чтобы сделать Java более совершенной.

Оригинал: “https://dev.to/rvprasad/groovier-groovy-with-java-8-streams-9l7”