Как Stream.count () работает для запросов к репозиторию Spring? - PullRequest
2 голосов
/ 12 февраля 2020

Я работаю в среде Spring и использую хранилище для загрузки данных в виде потока. Ниже приведен код, который используется:

@Query("select j from User j ")
@QueryHints({ @QueryHint(name = HINT_FETCH_SIZE, value = Constants.JPA_QUERYHINT_FETCH_SIZE) })
Stream<User> streamAll();

Когда мы вызываем метод service.getStream().count(), загружается ли полный набор данных в память или есть мета-информация о размере потока?

Здесь меня беспокоит потребление памяти и производительность.

Ответы [ 2 ]

1 голос
/ 12 февраля 2020

Потоки ленивы

Это означает, что результаты не извлекаются до тех пор, пока не будет вызвана операция терминала .

Однако count() является операцией терминала, поэтому конвейер выполняется .

Потоки также имеют короткое замыкание

Это означает, что если пройдено достаточное количество элементов для успешного выполнения операции, больше элементов не будет пройдено. Так обстоит дело, например, с findFirst().

Однако операция count() предлагает подсчитать все элементы, что требует прохождения всех элементов для получения результата. .

Теперь хорошая новость заключается в том, что некоторую информацию можно напрямую запрашивать из источника потока. Одним из таких примеров является количество элементов, когда в потоке установлен флаг SIZED. Поток тогда достаточно умен, чтобы напрямую получать информацию из источника потока, вместо того, чтобы обойти все элементы. Эта оптимизация была ошибочно не реализована в Java 8, а реализована в Java 9 .

Поставщик потока

Характеристики задаются поставщиком поток. И будет ли count() коротким замыканием, в конце концов, решать поставщику потоков.

1 голос
/ 12 февраля 2020

Попробуйте сами.

Если это возвращает true, то можно получить счет без итерации.

Если это возвращает false, вам придется выполнить итерацию.

myRepo.streamAll().spliterator().hasCharacteristics(Spliterator.SIZED)

Немного сложно проверить реализацию, поскольку Spring создает динамический c прокси для репозиториев .

Полагаю, нечего сказать, что даже если эта оптимизация не сейчас нет, что может быть недоступно в будущем. Вероятно, также зависит от поставщика БД, поскольку не все из них имеют способ O (1) получить количество строк (обычно это достигается путем сохранения его в виде метаданных таблицы).

...