2014-10-10 16 views
36

Voglio parallelizzare il codice seguente snipped utilizzando un parallelStream:Flusso di valori booleani, è vero?

boolean anyTrue() { 
    for (Element e : setOfE) { 
    if (eval(e)) { 
     return true; 
    } 
    } 
    return false; 
} 

disposta la seguente lavoro sui flussi paralleli e l'uso regolare di valutazione di corto circuito?

setOfE.parallelStream().map(e -> eval(e)).reduce(false, (a,b) -> a || b)) 

risposta

76

Streams API ha in realtà di prima classe di supporto per il vostro requisito:

setOfE.parallelStream().anyMatch(e->eval(e)); 

Al contrario di vostro approccio con reduce, questo è garantito avere una valutazione di cortocircuito e sfruttare in modo ottimale il parallelismo.

12

No, la riduzione non supporta la valutazione di cortocircuito. Il motivo è che reduce riceve appena un'implementazione arbitraria BinaryOperator e non ha idea delle possibilità di cortocircuito della particolare operazione.

Ma è possibile eseguire l'intera operazione molto più semplice:

setOfE.parallelStream().filter(e -> eval(e)).findAny().isPresent() 

Questo cerca semplicemente per un elemento arbitrario per il quale eval rendimenti true e findAny permette di terminare l'operazione non appena un thread ha riscontrato una corrispondenza. Il risultante Optional può essere interrogato per essere vuoto in quanto non ti interessa il particolare abbinamento Element.

In alternativa è possibile utilizzare come suggerito dal commento di Marko Topolnik:

setOfE.parallelStream().anyMatch(e -> eval(e)) 
Problemi correlati