Skip to content

Commit d52a7c4

Browse files
committed
feat(streams): 🎸 parallel streams, translated
Refers: #7
1 parent de27189 commit d52a7c4

File tree

8 files changed

+65
-67
lines changed

8 files changed

+65
-67
lines changed
Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,208 +1,206 @@
11
:java-package: src/org/j6toj8/streams
22
:section-java-package: ../../../{java-package}
33

4-
=== Streams Paralelos
4+
=== Parallel Streams
55

6-
.Objetivo
6+
.Objective
77
--------------------------------------------------
88
Develop code that uses parallel streams, including decomposition operation and reduction operation in streams
9-
-
10-
Desenvolver código que usa Streams Paralelos, incluindo operação de decomposição e operação de redução em Streams
119
--------------------------------------------------
1210

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.
11+
_Streams_ can be sequential or parallel. Sequential was seen in the previous section, while parallels will be presented in this section. Parallel _Streams_ are executed by more than one _Thread_, usually equal to the number of processor cores where the application is running. Nevertheless, it is not always useful to use them. Your actual gain is _Streams_ using large volumes of data. In a small _Stream_, turning it parallel can even cause a loss of performance.
1412

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.
13+
When using any kind _Stream_, it is recommended not to perform Lambda functions that cause side effects, such as changes in the state of objects. In parallel _Streams_, this recommendation is even more important.
1614

17-
. É possível transformar qualquer _Stream_ em paralelo utilizando o método `parallel`.
15+
. You can make any _Stream_ parallel using the `parallel` method.
1816
+
1917
[source,java,indent=0]
2018
.{java-package}/parallelstreams/Streams_Parallel.java
2119
----
2220
include::{section-java-package}/parallelstreams/Streams_Parallel.java[tag=code]
2321
----
2422

25-
. É possível criar _Streams_ paralelos diretamente em Coleções através do método `parallelStream`.
23+
. You can create parallel _Streams_ directly in Collections through the `parallelStream` method.
2624
+
2725
[source,java,indent=0]
2826
.{java-package}/parallelstreams/Streams_ParallelStream.java
2927
----
3028
include::{section-java-package}/parallelstreams/Streams_ParallelStream.java[tag=code]
3129
----
3230

33-
. Ao utilizar a operação `forEach` em um _Stream_ paralelo, a ordem de execução não é garantida.
31+
. When using the `forEach` operation on a parallel _Stream_, the order of execution is not guaranteed.
3432
+
3533
[source,java,indent=0]
3634
.{java-package}/parallelstreams/Streams_ParallelForEach.java
3735
----
3836
include::{section-java-package}/parallelstreams/Streams_ParallelForEach.java[tag=code]
3937
----
4038
+
41-
.Saída no console
39+
.console output
4240
[source,console]
4341
----
44-
Sequencial:
42+
Sequential:
4543
A
4644
B
4745
C
48-
Paralelo:
46+
Parallel:
4947
B
5048
C
5149
A
5250
----
5351
+
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.
52+
The parallel _Stream_ could have printed in any order as there is no guarantee in the order in which the elements will be handled.
5553

56-
. A operação `forEachOrdered` garante que a ordem será mantida mesmo em _Streams_ paralelos.
54+
. The `forEachOrdered` operation ensures that order will be maintained even in parallel _Streams_.
5755
+
5856
[source,java,indent=0]
5957
.{java-package}/parallelstreams/Streams_ParallelForEachOrdered.java
6058
----
6159
include::{section-java-package}/parallelstreams/Streams_ParallelForEachOrdered.java[tag=code]
6260
----
6361
+
64-
.Saída no console
62+
.console output
6563
[source,console]
6664
----
67-
Sequencial:
65+
Sequential:
6866
A
6967
B
7068
C
71-
Paralelo:
69+
Parallel:
7270
A
7371
B
7472
C
7573
----
7674

77-
. Em coleções com muitos objetos pode haver um ganho considerável de performance.
75+
. In collections with many objects, there can be a considerable performance gain.
7876
+
7977
[source,java,indent=0]
8078
.{java-package}/parallelstreams/Streams_ParallelPerformance.java
8179
----
8280
include::{section-java-package}/parallelstreams/Streams_ParallelPerformance.java[tag=code]
8381
----
8482
+
85-
.Saída no console
83+
.console output
8684
[source,console]
8785
----
88-
Tempo stream sequencial: 9863
89-
Tempo stream paralelo: 1479
86+
Sequential Stream time: 9863
87+
Parallel Stream time: 1479
9088
----
9189
+
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.
90+
Note that on the machine where the code was executed, parallel execution took only 15% of the sequential execution time. This is not a thorough test, but it does show the potential of parallel _Streams_.
9391

94-
. Operações intermediárias que alteram o estado de objetos podem gerar resultados inesperados ao serem executadas em paralelo.
92+
. Intermediate operations that change the state of objects can produce unexpected results when executed in parallel.
9593
+
9694
[source,java,indent=0]
9795
.{java-package}/parallelstreams/Streams_ParallelStatefulOperation.java
9896
----
9997
include::{section-java-package}/parallelstreams/Streams_ParallelStatefulOperation.java[tag=code]
10098
----
10199
+
102-
.Saída no console
100+
.console output
103101
[source,console]
104102
----
105-
Ordem no forEachOrdered:
103+
Order on forEachOrdered:
106104
A
107105
B
108106
C
109-
Ordem na synchronizedList:
107+
Order on synchronizedList:
110108
A
111109
C
112110
B
113111
----
114112
+
115-
Perceba que a ordem foi respeitada na última operação do _Stream_, o `forEachOrdered`, mas não foi respeitada na execução da operação intermediária `map`. Isso ocorre porque essa operação intermediária não precisa seguir a ordem dos itens do stream.
113+
Note that the order was respected in the last _Stream_ operation, `forEachOrdered`, but was not respected when performing the `map` intermediate operation. This is because this intermediate operation does not have to follow the order of stream items.
116114

117-
. Diferente da execução em um _Stream_ sequencial, a operação `findAny` traz resultados realmente aleatórios ao ser executada em um _Stream_ paralelo.
115+
. Unlike running in a sequential _Stream_, the `findAny` operation brings really random results when executed in a parallel _Stream_.
118116
+
119117
[source,java,indent=0]
120118
.{java-package}/parallelstreams/Streams_ParallelFindAny.java
121119
----
122120
include::{section-java-package}/parallelstreams/Streams_ParallelFindAny.java[tag=code]
123121
----
124122
+
125-
.Saída no console
123+
.console output
126124
[source,console]
127125
----
128-
findAny Sequencial: 7
129-
findAny Paralelo: 9
126+
findAny Sequential: 7
127+
findAny Parallel: 9
130128
----
131129

132-
. Ao realizar uma operação de reduce não há problema caso o acumulador seja associativo.
130+
. When performing a reduce operation there is no problem if the accumulator is associative.
133131
+
134132
[source,java,indent=0]
135133
.{java-package}/parallelstreams/Streams_ParallelReduceAssociative.java
136134
----
137135
include::{section-java-package}/parallelstreams/Streams_ParallelReduceAssociative.java[tag=code]
138136
----
139137
+
140-
.Saída no console
138+
.console output
141139
[source,console]
142140
----
143141
13440
144142
13440
145143
----
146144
+
147-
Perceba que o resultado com o Stream sequencial é idêntico ao paralelo. Isso ocorre porque a operação de multiplicação é associativa, ou seja, fazer `(2 x 2) x (3 x 3)` é o mesmo que fazer `(2 x 2 x 3) x 3`, ou até mesmo `2 x (2 x 3) x 3`.
145+
Note that the result with sequential Stream is identical to parallel. This is because the multiplication operation is associative, i.e., doing `(2 x 2) x (3 x 3)` is the same as doing `(2 x 2 x 3) x 3`, or even `2 x (2x3) x3`.
148146

149-
. Ao realizar uma operação de reduce acumuladores não-associativos irá gerar resultados inesperados.
147+
. Performing a reduce non-associative accumulator operation will produce unexpected results.
150148
+
151149
[source,java,indent=0]
152150
.{java-package}/parallelstreams/Streams_ParallelReduceNonAssociative.java
153151
----
154152
include::{section-java-package}/parallelstreams/Streams_ParallelReduceNonAssociative.java[tag=code]
155153
----
156154
+
157-
.Saída no console
155+
.console output
158156
[source,console]
159157
----
160158
-18
161159
8
162160
----
163161
+
164-
Isso ocorre pois a operação de subtração não é associativa, então o resultado pode variar conforme o _Stream_ for "fatiado" para ser executado em paralelo. Ou seja, fazer `1 - 2 - 3 - 4` não é o mesmo que fazer `(1 - 2) - (3 - 4)`.
162+
This is because the subtraction operation is not associative, so the result may vary as _Stream_ is "sliced" to run in parallel. That is, doing `1 - 2 - 3 - 4` is not the same as doing `(1 - 2) - (3 - 4)`.
165163

166-
. Para coletar o resultado de um _Stream_ paralelo em um mapa, utilize a operação `toConcurrentMap`.
164+
. To collect the result of a parallel _Stream_ on a map, use the `toConcurrentMap` operation.
167165
+
168166
[source,java,indent=0]
169167
.{java-package}/parallelstreams/Streams_ParallelToConcurrentMap.java
170168
----
171169
include::{section-java-package}/parallelstreams/Streams_ParallelToConcurrentMap.java[tag=code]
172170
----
173171
+
174-
.Saída no console
172+
.console output
175173
[source,console]
176174
----
177175
toMap: {Roseany=7, Amélia=6, Rodrigo=7, Rinaldo=7, Luiz=4}
178176
toConcurrentMap: {Amélia=6, Roseany=7, Rodrigo=7, Rinaldo=7, Luiz=4}
179177
----
180178
+
181-
Perceba que o resultados das operações pode ser diferente. Ao utilizar o _Collector_ `toConcurrentMap` em um _Stream_ paralelo, as operações podem ser executadas em qualquer ordem e não há necessidade de criar múltiplos `Map's` para serem combinados posteriormente. Em grandes _Streams_, isso pode ocasionar em um ganho de performance.
179+
Note that the results of operations may differ. By using _Collector_ `toConcurrentMap` in a parallel _Stream_, operations can be performed in any order and there is no need to create multiple `Map's` to be combined later. In large _Streams_, this can lead to a performance gain.
182180

183-
. Para coletar o resultado de um Stream paralelo utilize _groupingByConcurrent_ ao invés de _groupingBy_.
181+
. To collect the result of a parallel stream use _groupingByConcurrent_ instead of _groupingBy_.
184182
+
185183
[source,java,indent=0]
186184
.{java-package}/parallelstreams/Streams_ParallelGroupingByConcurrent.java
187185
----
188186
include::{section-java-package}/parallelstreams/Streams_ParallelGroupingByConcurrent.java[tag=code]
189187
----
190188
+
191-
.Saída no console
189+
.console output
192190
[source,console]
193191
----
194192
{4=[Luiz], 6=[Amélia], 7=[Rinaldo, Rodrigo, Roseany]}
195193
{4=[Luiz], 6=[Amélia], 7=[Roseany, Rodrigo, Rinaldo]}
196194
----
197195
+
198-
Pelo mesmo motivo do exemplo anterior, a ordem pode variar ao utilizar o `groupingByConcurrent`, porém pode haver ganho de performance em grandes _Streams_ paralelos, pois a ordem não é necessariamente seguida e não há necessidade de criar múltiplos mapas.
196+
For the same reason as in the previous example, the order may vary when using `groupingByConcurrent`, but there may be performance gains on large parallel _Streams_ as the order is not necessarily followed and there is no need to create multiple maps.
199197

200-
.Referências
198+
.References
201199
****
202200
203201
* Working with Parallel Streams
204202
+
205-
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 366). Wiley. Edição do Kindle.
203+
Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8 Programmer II Study Guide (p. 366). Wiley. Kindle Edition.
206204
207205
* https://www.baeldung.com/java-8-streams[The Java 8 Stream API Tutorial.]
208206
@@ -212,4 +210,4 @@ Boyarsky, Jeanne; Selikoff, Scott. OCP: Oracle Certified Professional Java SE 8
212210
213211
* https://docs.oracle.com/javase/8/docs/api/?java/util/stream/Stream.html[Interface Stream<T>.] Java Plataform SE 8.
214212
215-
****
213+
****

src/org/j6toj8/streams/parallelstreams/Streams_Parallel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static void main(String[] args) {
88
// tag::code[]
99
String[] array = new String[] { "A", "B", "C" };
1010
Arrays.stream(array)
11-
.parallel() // stream transformado em paralelo
11+
.parallel() // stream transformed in parallel
1212
.forEach(System.out::println);
1313
// end::code[]
1414
}

src/org/j6toj8/streams/parallelstreams/Streams_ParallelFindAny.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ public static void main(String[] args) {
99
// tag::code[]
1010
Optional<Integer> findAny1 = Stream.of(7, 2, 1, 8, 4, 9, 2, 8)
1111
.findFirst();
12-
System.out.println("findAny Sequencial: " + findAny1.get());
12+
System.out.println("findAny Sequential: " + findAny1.get());
1313

1414
Optional<Integer> findAny2 = Stream.of(7, 2, 1, 8, 4, 9, 2, 8)
1515
.parallel()
1616
.findAny();
17-
System.out.println("findAny Paralelo: " + findAny2.get());
17+
System.out.println("findAny Parallel: " + findAny2.get());
1818
// end::code[]
1919
}
2020
}

src/org/j6toj8/streams/parallelstreams/Streams_ParallelForEach.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ public static void main(String[] args) {
99
// tag::code[]
1010
List<String> list = Arrays.asList("A", "B", "C");
1111

12-
System.out.println("Sequencial: ");
13-
list.stream() // cria um Stream sequencial
12+
System.out.println("Sequential: ");
13+
list.stream() // create a sequential stream
1414
.forEach(System.out::println);
1515

16-
System.out.println("Paralelo: ");
17-
list.parallelStream() // cria um Stream paralelo
16+
System.out.println("Parallel: ");
17+
list.parallelStream() // create a parallel stream
1818
.forEach(System.out::println);
1919
// end::code[]
2020
}

src/org/j6toj8/streams/parallelstreams/Streams_ParallelForEachOrdered.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ public static void main(String[] args) {
99
// tag::code[]
1010
List<String> list = Arrays.asList("A", "B", "C");
1111

12-
System.out.println("Sequencial: ");
13-
list.stream() // cria um Stream sequencial
12+
System.out.println("Sequential: ");
13+
list.stream() // create a sequential stream
1414
.forEachOrdered(System.out::println);
1515

16-
System.out.println("Paralelo: ");
17-
list.parallelStream() // cria um Stream paralelo
16+
System.out.println("Parallel: ");
17+
list.parallelStream() // create a parallel stream
1818
.forEachOrdered(System.out::println);
1919
// end::code[]
2020
}

src/org/j6toj8/streams/parallelstreams/Streams_ParallelPerformance.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ public class Streams_ParallelPerformance {
66

77
public static void main(String[] args) {
88
// tag::code[]
9-
long inicio = System.currentTimeMillis();
10-
IntStream.range(0, Integer.MAX_VALUE) // stream sequencial
9+
long start = System.currentTimeMillis();
10+
IntStream.range(0, Integer.MAX_VALUE) // sequential stream
1111
.mapToDouble(n -> Math.pow(n, 2))
1212
.average()
13-
.ifPresent(n -> System.out.println("Tempo stream sequencial: " + (System.currentTimeMillis() - inicio)));
13+
.ifPresent(n -> System.out.println("Sequential Stream time: " + (System.currentTimeMillis() - start)));
1414

15-
long inicio2 = System.currentTimeMillis();
15+
long start2 = System.currentTimeMillis();
1616
IntStream.range(0, Integer.MAX_VALUE)
17-
.parallel() // stream paralelo
17+
.parallel() // parallel stream
1818
.mapToDouble(n -> Math.pow(n, 2))
1919
.average()
20-
.ifPresent(n -> System.out.println("Tempo stream paralelo: " + (System.currentTimeMillis() - inicio2)));
20+
.ifPresent(n -> System.out.println("Parallel Stream time: " + (System.currentTimeMillis() - start2)));
2121
// end::code[]
2222
}
2323
}

src/org/j6toj8/streams/parallelstreams/Streams_ParallelStatefulOperation.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ public static void main(String[] args) {
1212
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
1313
List<String> list = Arrays.asList("A", "B", "C");
1414

15-
System.out.println("Ordem no forEachOrdered: ");
15+
System.out.println("Order on forEachOrdered: ");
1616
list.parallelStream()
17-
.map(s -> {synchronizedList.add(s); return s;}) // operação com efeito colateral - altera o estado de um objeto
17+
.map(s -> {synchronizedList.add(s); return s;}) // side effect operation - changes the state of an object
1818
.forEachOrdered(System.out::println);
1919

20-
System.out.println("Ordem na synchronizedList: ");
20+
System.out.println("Order on synchronizedList: ");
2121
for (String s : synchronizedList) {
2222
System.out.println(s);
2323
}

src/org/j6toj8/streams/parallelstreams/Streams_ParallelStream.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class Streams_ParallelStream {
88
public static void main(String[] args) {
99
// tag::code[]
1010
List<String> list = Arrays.asList("A", "B", "C");
11-
list.parallelStream() // cria um Stream paralelo diretamente
11+
list.parallelStream() // create a parallel stream directly
1212
.forEach(System.out::println);
1313
// end::code[]
1414
}

0 commit comments

Comments
 (0)