Commit 3bd9dc7a authored by Dominikus Herzberg's avatar Dominikus Herzberg

Performanzmessung ergänzt

parent 2fa0fb03
......@@ -2,6 +2,8 @@
Der kleine [Carl Friedrich Gauß](https://de.wikipedia.org/wiki/Carl_Friedrich_Gau%C3%9F) bekam in der Schule von seinem Lehrer eine einfache Aufgabe gestellt: "Berechne mir die Summe der Zahlen von 1 bis 100!" Vermutlich erhoffte sich der Lehrer, Carl Friedrich für eine Weile ruhig zu stellen mit der mühsamen schriftlichen Addition der Zahlen. Der aber gab nach kurzer Zeit das Ergebnis bekannt: 5050. (Der [Rechenkniff](https://de.wikipedia.org/wiki/Carl_Friedrich_Gau%C3%9F#Eltern,_Kindheit_und_Jugend) ist auf Wikipedia nachzulesen.)
## Gauß deklarativ programmiert
Wie hätten Sie die Aufgabe in Java umgesetzt? Mit einer Schleife? Es geht anders!
~~~
......@@ -40,4 +42,54 @@ jshell> IntStream.rangeClosed(1,10).peek(System.out::println).sum()
9
10
$4 ==> 55
~~~
\ No newline at end of file
~~~
## Sind Streams nicht langsamer als `for`-Schleifen?
Performanz-Messungen sind eine komplizierte Sache, nicht nur in Java. Aber um ein Gefühl für die Unterschiede in der Ausführung zu bekommen, vergleichen wir die Laufzeiten der folgenden Arten, die Summe der Zahlen von 1 bis 1 Milliarde zu bestimmen.
1. Variante: Ein Strom aus Zahlen
```
LongStream.rangeClosed(1,1_000_000_000).sum();
```
2. Variante: Ein paralleler Strom aus Zahlen
```
LongStream.rangeClosed(1,1_000_000_000).parallel().sum();
```
3. Variante: Eine `for`-Schleife
```
long sum = 0;
for(long x = 1; x <= 1_000_000_000; x++) sum += x;
```
Ich habe diese Code-Fragmente mit dem folgenden Stückchen Code mit Hilfe der JShell ausgeführt und vermessen. Die Ausgabe ist in Millisekunden.
~~~ Java
int N = 40;
long start, stopp;
long add = 0;
for(int i = 1; i <= N; i++) {
start = System.nanoTime();
// insert code snippet here
stopp = System.nanoTime();
add += stopp - start;
}
System.out.println(add/N/1_000_000L);
~~~
Auf meinem Laptop (Intel i7-5500U, 2.40GHz, 2 Kerne) ergeben sich folgende Laufzeiten:
| Variante | 1. | 2. | 3. |
| -------- | ----- | ----- | ----- |
| ms | 682 | 317 | 468 |
Der nicht-parallelisierte Stream ist um 45% langsamer als die `for`-Schleife. Das ist ein bezahlbarer Preis für deklarativen Code. Allerdings schenkt einem `parallel()` bei zwei Kernen einen doppelt so schnellen Code, was beeindruckend ist. Jetzt erledigt der Strom die Arbeit um 32% schneller als die `for`-Schleife.
> Fazit: Unterschätze die Performanz eines deklarativen Programmierstils nicht, vor allem `parallel()` kann sich als echter Durchstarter erweisen.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment