В моей программе я повторно 1collect Java 8 потоки, чтобы уменьшить совокупность объектов до одного. Размер этой коллекции может сильно различаться на протяжении всего исполнения: от 3 объектов до сотен.
public void findInterestingFoo(Stream<Foo> foos) {
internalState.update(foos.collect(customCollector()));
}
В процессе оптимизации моего кода и поиска узких мест я сделал поток parallel в какой-то момент. Это сработало в тот момент, поскольку коллекции были довольно большими. Позже, изменив другие части и параметры программы, коллекции стали меньше. Я понял, что не сделать параллельный поток более эффективным. Это имеет смысл: накладные расходы по распределению работы над несколькими потоками для 4 объектов просто не стоят. Однако это стоит для сотен объектов.
Было бы очень удобно, если бы я мог сделать только большие потоки параллельными:
public void findInterestingFoo(Stream<Foo> foos) {
if (isSmall(foos)) {
internalState.update(foos.collect(customCollector()));
} else {
internalState.update(foos.parallel().collect(customCollector()));
}
}
Конечно, это можно сделать вручную, когда поток создается из массива, коллекция, или вручную. То есть мы знаем, какие элементы входят в поток, поэтому это можно отслеживать. Тем не менее, я заинтересован в решении этого в общем виде, так что независимо от того, какой поток передается на findInterestingFoo
, он обрабатывается надлежащим образом и максимально эффективно.
Что-то вроде count()
может помочь, за исключением того, что он завершает поток, прежде чем я смогу collect it.
Мне хорошо известно, что потоки предназначены для не заданного размера, в частности:
- Возможно неограниченное. Хотя коллекции имеют конечный размер, потоки не нужны. Операции короткого замыкания, такие как
limit(n)
илиfindFirst()
, позволяют завершить вычисления в бесконечных потоках за конечное время. —java.util.stream
описание пакета
Тем не менее, мне интересно, есть ли способ определить, сколько элементов находится в потоке, прежде чем выполнять какие-либо операции над ним. Неужели поток действительно не знает, что он создан из конечной коллекции?
__________
1 Тысячи раз. Оптимизация этого привела к ускорению от общего времени работы от 1,5 до 0,5 секунд в моем случае.