A API Stream foi projetada para facilitar a gravação de cálculos de uma maneira que foi abstraída da maneira como eles seriam executados, facilitando a alternância entre seqüencial e paralelo.
No entanto, só porque é fácil, não significa que é sempre uma boa ideia e, de fato, é uma má idéia simplesmente cair .parallel()
por todo o lugar simplesmente porque você pode.
Primeiro, observe que o paralelismo não oferece outros benefícios além da possibilidade de execução mais rápida quando houver mais núcleos disponíveis. Uma execução paralela sempre envolverá mais trabalho do que seqüencial, porque além de resolver o problema, ela também deve executar o envio e a coordenação de subtarefas. A esperança é que você consiga chegar à resposta mais rapidamente, dividindo o trabalho em vários processadores; se isso realmente acontece depende de muitas coisas, incluindo o tamanho do seu conjunto de dados, quanta computação você está fazendo em cada elemento, a natureza da computação (especificamente, o processamento de um elemento interage com o processamento de outros?) , o número de processadores disponíveis e o número de outras tarefas que competem por esses processadores.
Além disso, observe que o paralelismo também frequentemente expõe o não determinismo na computação que geralmente é oculta por implementações seqüenciais; às vezes isso não importa ou pode ser mitigado restringindo as operações envolvidas (ou seja, os operadores de redução devem ser apátridas e associativos).
Na realidade, às vezes o paralelismo acelera a computação, às vezes não, e às vezes até diminui a velocidade. É melhor desenvolver primeiro usando a execução sequencial e depois aplicar o paralelismo onde
(A) você sabe que há realmente benefícios em aumentar o desempenho e
(B) que realmente proporcionará um desempenho aprimorado.
(A) é um problema comercial, não técnico. Se você é um especialista em desempenho, geralmente poderá analisar o código e determinar (B), mas o caminho inteligente é medir. (E nem se preocupe até que você esteja convencido de (A); se o código for rápido o suficiente, melhor aplicar seu cérebro a outros lugares.)
O modelo de desempenho mais simples para paralelismo é o modelo "NQ", em que N é o número de elementos e Q é o cálculo por elemento. Em geral, você precisa que o NQ do produto exceda algum limite antes de começar a obter um benefício de desempenho. Para um problema de baixa Q, como "some números de 1 a N", geralmente você verá um ponto de equilíbrio entre N = 1000 e N = 10000. Com problemas com Q mais alto, você verá interrupções em limites mais baixos.
Mas a realidade é bastante complicada. Portanto, até que você atinja a perícia, primeiro identifique quando o processamento seqüencial realmente está lhe custando algo e depois avalie se o paralelismo ajudará.