Поток Java 8, List.subList или Stream.skip (). Limit () - PullRequest
0 голосов
/ 26 марта 2019

Мне нужно пройти курс лечения на странице списка. Поэтому мне интересно, что лучше (в производительности и в хорошей практике) между:

public List<Other> function(List<Something> somethingList, 
                            int offset, int pageSize) {
    return somethingList.stream().skip(offset * pageSize).limit(pageSize)
        .map(s -> doSomething(s)).collect(Collectors.toList());
}

или:

public List<Other> function(List<Something> somethingList, 
                            int offset, int pageSize) {
    return somethingList.subList(offset * pageSize, offset * pageSize + pageSize)
        .stream().map(s -> doSomething).collect(Collectors.toList());
}

Я добровольно пропустил проверку смещения и размера страницы.

Редактировать: Это не жизненная необходимость производительности, мой вопрос также о ясности, обслуживании и хорошей практике. Я предпочитаю способ потока, особенно потому, что он требует меньше проверки. Но я предпочитаю быть уверенным, что это не реальная потеря производительности или менее удобные / чистые вещи.

1 Ответ

2 голосов
/ 26 марта 2019

Разница в порядке потоковых операций. Java Stream API . Состояния, которые пропускают дешево.

Хотя skip () обычно является дешевой операцией для последовательных потоковых конвейеров, она может быть довольно дорогой для упорядоченных параллельных конвейеров, особенно для больших значений n, так как skip (n) ограничен пропуском не только любых n элементов, но и первые n элементов в порядке встречи. Использование неупорядоченного источника потока (например, generate (Supplier)) или удаление ограничения упорядочения с помощью BaseStream.unordered () может привести к значительному ускорению skip () в параллельных конвейерах, если семантика вашей ситуации позволяет. Если требуется согласованность с порядком встреч, и вы испытываете низкую производительность или использование памяти при использовании skip () в параллельных конвейерах, переключение на последовательное выполнение с помощью BaseStream.sequential () может повысить производительность.

и

Limit: возвращает поток, состоящий из элементов этого потока, дополнительно выполняя предоставленное действие для каждого элемента, когда элементы потребляются из результирующего потока.

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

Пока ваш вопрос очень конкретный. Эти же принципы будут применяться к тому, что происходит под капотом в списке. Мощность потоков . Под капотом у вас все еще может быть несколько предметов из потока; но сложность снимается с программиста при выполнении сложных операций над набором элементов. Проще говоря, это может заменить многие спина к спине для циклов, где мы используем топовые элементы процесса. Они действительно полезны. Потоки можно заменить на петли .

...