2015-08-02 2 views
4

Я контролирую Потребителя, которые получают это для этого, так что его могут или не могут попросить выполнить какое-либо действие.Будет ли Java 8 Stream.forEach (x -> {}); Делать что-нибудь?

list.parallelStream().forEach(x-> {}); 

Потоки ленивые Потоки не будут проходить, так? Ничего не произойдет, что я ожидаю. Скажите, пожалуйста, если я ошибаюсь.

+1

Проверьте сгенерированный байт-код, но я ожидаю увидеть оптимизацию здесь. –

+0

ForEach - это терминал op, который инициирует оценку потока. Элементы будут сгенерированы и переданы в лямбду do-nothing. –

ответ

5

Он будет перемещаться по всему потоку, представляя задачи для объединения пулов, разбивая список на части и передавая все элементы списка этой пустой лямбда. В настоящее время невозможно проверить во время выполнения, является ли выражение лямбда пустым или нет, поэтому его невозможно оптимизировать.

Аналогичная проблема возникает при использовании Collector. Все коллекторы имеют операцию finisher, но во многих случаях это функция идентификации, такая как x -> x. В этом случае иногда код, который использует коллекторы, может быть сильно оптимизирован, но вы не можете точно определить, является ли предоставленная лямбда личность или нет. Для этого вместо этого была введена дополнительная характеристика коллектора под названием IDENTITY_FINISH. Если бы можно было надежно определить, является ли предоставленная лямбда функцией идентификации, эта характеристика не нужна.

Также смотрите JDK-8067971 обсуждение. Это предполагает создание статических констант, таких как Predicate.TRUE (всегда верно) или Predicate.FALSE (всегда false) для оптимизации таких операций, как Stream.filter. Например, если подано Predicate.TRUE, тогда можно удалить этап фильтрации, и если будет предоставлен Predicate.FALSE, тогда поток может быть заменен пустым потоком в этой точке. Опять же, можно было обнаружить во время выполнения, что поставленный предикат всегда прав, тогда было бы необязательно создавать такие константы.

+0

Есть ли у вас какие-либо источники или доказательства этого иска? Требование кажется разумным, но я лично ожидал бы, что оптимизирована пустая функция потока (если предположить, что это действительно пустая лямбда, о которой на самом деле не говорится). – Vulcan

+0

Отличное редактирование. Интересно, будет ли компилятор JIT в конечном итоге поддерживать оптимизацию вокруг лямбда, так как это похоже на хорошую функцию оптимизации, которая в конечном итоге будет реализована. – Vulcan

+3

Компилятор может оптимизировать некоторые вещи для * последовательных * потоков, когда все встраивается в один цикл, но для параллельных потоков очереди задач кросс-потоков по существу непрозрачны для JIT. Поток-конвейер должен был бы сделать какую-то интроспекцию на лямбдах, чтобы выполнить такую ​​оптимизацию. – the8472

Смежные вопросы