Skip to content

Commit 43610f3

Browse files
committed
feat(parallel-streams): 5 exemplos de streams paralelos
Adição de 5 exemplos sobre Streams paralelos. Ref. Issue #24
1 parent cdfe141 commit 43610f3

File tree

6 files changed

+174
-7
lines changed

6 files changed

+174
-7
lines changed

book/05-java-streams/sections/02-parallel-streams.asc

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,87 @@ Develop code that uses parallel streams, including decomposition operation and r
1010
Desenvolver código que usa Streams Paralelos, incluindo operação de decomposição e operação de redução em Streams
1111
--------------------------------------------------
1212

13-
Streams podem ser sequenciais ou paralelos. Os sequencias foram vistos na seção anterior, enquanto os paralelos serão apresentados nesta seção. Streams paralelos são executados por mais de uma Thread, geralmente uma quantidade igual à quantidade de núcleos do processador onde a aplicação está sendo executada. Apesar disso, nem sempre é útil utilizá-los. Seu ganho real é em Streams com grande volumes de dados. Em um Stream pequeno, transformá-lo em paralelo pode até causar uma perda de performance.
13+
_Streams_ podem ser sequenciais ou paralelos. Os sequencias foram vistos na seção anterior, enquanto os paralelos serão apresentados nesta seção. _Streams_ paralelos são executados por mais de uma _Thread_, geralmente uma quantidade igual à quantidade de núcleos do processador onde a aplicação está sendo executada. Apesar disso, nem sempre é útil utilizá-los. Seu ganho real é em _Streams_ com grande volumes de dados. Em um _Stream_ pequeno, transformá-lo em paralelo pode até causar uma perda de performance.
1414

15-
Ao utilizar qualquer tipo de Stream, é recomendável não executar funções lambdas que causem efeitos colaterais, como mudanças no estado de objetos. Em Streams paralelos essa recomendação é ainda mais forte.
15+
Ao utilizar qualquer tipo de _Stream_, é recomendável não executar funções lambdas que causem efeitos colaterais, como mudanças no estado de objetos. Em _Streams_ paralelos essa recomendação é ainda mais importante.
16+
17+
. É possível transformar qualquer _Stream_ em paralelo utilizando o método `parallel`.
18+
+
19+
[source,java,indent=0]
20+
.{java-package}/parallelstreams/Streams_Parallel.java
21+
----
22+
include::{section-java-package}/parallelstreams/Streams_Parallel.java[tag=code]
23+
----
24+
25+
. É possível criar _Streams_ paralelos diretamente em Coleções através do método `parallelStream`.
26+
+
27+
[source,java,indent=0]
28+
.{java-package}/parallelstreams/Streams_ParallelStream.java
29+
----
30+
include::{section-java-package}/parallelstreams/Streams_ParallelStream.java[tag=code]
31+
----
32+
33+
. Ao utilizar a operação `forEach` em um _Stream_ paralelo, a ordem de execução não é garantida.
34+
+
35+
[source,java,indent=0]
36+
.{java-package}/parallelstreams/Streams_ParallelForEach.java
37+
----
38+
include::{section-java-package}/parallelstreams/Streams_ParallelForEach.java[tag=code]
39+
----
40+
+
41+
.Saída no console
42+
[source,console]
43+
----
44+
Sequencial:
45+
A
46+
B
47+
C
48+
Paralelo:
49+
B
50+
C
51+
A
52+
----
53+
+
54+
O _Stream_ paralelo poderia ter impresso em qualquer ordem, pois não há nenhuma garantia na ordem em que os elementos serão tratados.
55+
56+
. A operação .forEachOrdered garante que a ordem será mantida mesmo em _Streams_ paralelos.
57+
+
58+
[source,java,indent=0]
59+
.{java-package}/parallelstreams/Streams_ParallelForEachOrdered.java
60+
----
61+
include::{section-java-package}/parallelstreams/Streams_ParallelForEachOrdered.java[tag=code]
62+
----
63+
+
64+
.Saída no console
65+
[source,console]
66+
----
67+
Sequencial:
68+
A
69+
B
70+
C
71+
Paralelo:
72+
A
73+
B
74+
C
75+
----
76+
77+
. Em coleções com muitos objetos pode haver um ganho considerável de performance.
78+
+
79+
[source,java,indent=0]
80+
.{java-package}/parallelstreams/Streams_ParallelPerformance.java
81+
----
82+
include::{section-java-package}/parallelstreams/Streams_ParallelPerformance.java[tag=code]
83+
----
84+
+
85+
.Saída no console
86+
[source,console]
87+
----
88+
Tempo stream sequencial: 9863
89+
Tempo stream paralelo: 1479
90+
----
91+
+
92+
Perceba que na máquina onde o código foi executado, a execução em paralelo demorou apenas 15% do tempo da execução sequencial. Esse não é um teste minucioso, mas mostra o potencial de _Streams_ paralelos.
1693

17-
. Chamando .parallel em Streams
18-
. Chamando .parallelStream em Coleções
19-
. Exemplo de .forEach com e sem paralelo, imprimindo em diferentes
20-
. Exemplo de .forEachOrdered em streams paralelos, que mantém ordem
21-
. Exemplo de ganho de performance
2294
. Evitar expressões lambda que alteram o estado de um objeto. Exemplo de forEachOrdered e um map com operação stateful.
2395
. Exemplo de findAny com resultados imprevisíveis
2496
. Utilização de unordered para ganhar performance em findFirst, limit, skip
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.j6toj8.streams.parallelstreams;
2+
3+
import java.util.Arrays;
4+
5+
public class Streams_Parallel {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
String[] array = new String[] { "A", "B", "C" };
10+
Arrays.stream(array)
11+
.parallel() // stream transformado em paralelo
12+
.forEach(System.out::println);
13+
// end::code[]
14+
}
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.streams.parallelstreams;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
6+
public class Streams_ParallelForEach {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
List<String> list = Arrays.asList("A", "B", "C");
11+
12+
System.out.println("Sequencial: ");
13+
list.stream() // cria um Stream sequencial
14+
.forEach(System.out::println);
15+
16+
System.out.println("Paralelo: ");
17+
list.parallelStream() // cria um Stream paralelo
18+
.forEach(System.out::println);
19+
// end::code[]
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.streams.parallelstreams;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
6+
public class Streams_ParallelForEachOrdered {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
List<String> list = Arrays.asList("A", "B", "C");
11+
12+
System.out.println("Sequencial: ");
13+
list.stream() // cria um Stream sequencial
14+
.forEachOrdered(System.out::println);
15+
16+
System.out.println("Paralelo: ");
17+
list.parallelStream() // cria um Stream paralelo
18+
.forEachOrdered(System.out::println);
19+
// end::code[]
20+
}
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.j6toj8.streams.parallelstreams;
2+
3+
import java.util.stream.IntStream;
4+
5+
public class Streams_ParallelPerformance {
6+
7+
public static void main(String[] args) {
8+
// tag::code[]
9+
long inicio = System.currentTimeMillis();
10+
IntStream.range(0, Integer.MAX_VALUE) // stream sequencial
11+
.mapToDouble(n -> Math.pow(n, 2))
12+
.average()
13+
.ifPresent(n -> System.out.println("Tempo stream sequencial: " + (System.currentTimeMillis() - inicio)));
14+
15+
long inicio2 = System.currentTimeMillis();
16+
IntStream.range(0, Integer.MAX_VALUE)
17+
.parallel() // stream paralelo
18+
.mapToDouble(n -> Math.pow(n, 2))
19+
.average()
20+
.ifPresent(n -> System.out.println("Tempo stream paralelo: " + (System.currentTimeMillis() - inicio2)));
21+
// end::code[]
22+
}
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.j6toj8.streams.parallelstreams;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
6+
public class Streams_ParallelStream {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
List<String> list = Arrays.asList("A", "B", "C");
11+
list.parallelStream() // cria um Stream paralelo diretamente
12+
.forEach(System.out::println);
13+
// end::code[]
14+
}
15+
}

0 commit comments

Comments
 (0)