StreamOpFlag.* and OutOfMemoryError when going parall
Christian Mallwitz
c.mallwitz at gmail.com
Wed Dec 5 10:54:21 PST 2012
Very well :-)
Leaving the parallel aspect aside, If I just wanted to find the first
n prime numbers based on a possibly infinity stream of numbers (I
don't want to use a Collection with a known size), is there another
'officially' approved way to covert an Iterator to a Stream (instead
of using Streams.stream())?
Regarding a fully lazy, parallel limit() and its future: does 'future'
mean pre- or post-JDK8?
Cheers!
Christian
On Wed, Dec 5, 2012 at 6:34 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> There's a good reason you are struggling with it -- this API is not intended
> for "casual" builders of streams. The intention is that 99.9% of users will
> never write code to call the Streams.stream() method directly; they will use
> arrays, collections, generators, or other packaged providers of streams.
>
> A safe default is 0. You can OR together the IS_ version of the flags if
> you know something about the nature of your stream. You probably want
> IS_ORDERED if you want to represent a stream for which the order of elements
> means something (e.g., a range generator, a List, an array, etc.)
>
> The reason it is failing with OOME is that the parallel implementation of
> limit() computes the entire results rather than operating fully lazily.
> While it would be preferable to operate more lazily, a lazy parallel
> implementation of operations like limit is not trivial. We hope to improve
> this in the future.
>
> On 12/5/2012 1:18 PM, Christian Mallwitz wrote:
>>
>> Hi,
>>
>> Using lambda-8-b67-linux-i586-03_dec_2012 I'm trying to compute n (not
>> necessarily the first n) prime numbers:
>>
>> import java.util.*;
>> import java.util.function.*;
>> import java.util.stream.*;
>>
>> public class LambdaExample3 {
>>
>> public static boolean isPrime(long n) {
>> if (n <= 1) { return false; }
>> if (n == 2) { return true; }
>> for (int i = 2; i <= Math.sqrt(n) + 1; i++) { if (n % i == 0)
>> return false; }
>> return true;
>> }
>>
>> public static void main(String[] args) {
>>
>> Stream<Long> stream =
>> Streams.parallel(Streams.spliteratorUnknownSize(new Iterator<Long>() {
>> private long n = 0;
>> @Override public boolean hasNext() { return true; }
>> @Override public Long next() { return ++n; }
>> }),
>> // fails with OutOfMemoryError
>> // StreamOpFlag.toStreamFlags(StreamOpFlag.NOT_SIZED,
>> StreamOpFlag.INITIAL_OPS_VALUE)
>> // fails with OutOfMemoryError
>> // StreamOpFlag.NOT_SIZED
>> // works, but no speed-up to non-parallel version
>> StreamOpFlag.INITIAL_OPS_VALUE
>> );
>>
>> stream
>> .filter(LambdaExample3::isPrime)
>> .limit(300000)
>> .forEach(l -> { /*System.out.println(l);*/ });
>> }
>> }
>>
>> I'm struggling with the StreamOpFlag parameter. What should I pick?
>> INITIAL_OPS_VALUE seems to work but isn't running anything in parallel
>> (at least it is not faster than the serial version). NOT_SIZED isn't
>> working but failing miserably with an OutOfMemoryError. IS_PARALLEL
>> is not needed because I already use parallel() - should specifying
>> IS_PARALLEL and using Streams.stream() supposed to go parallel as
>> well?
>>
>> Is the OutOfMemoryError caused by a bug? The OutOfMemoryError is
>> reported from a fork/join pool thread so at least it is going
>> parallel? Am I missing something?
>>
>> Thanks
>> Christian
>>
>
More information about the lambda-dev
mailing list