Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Leistung in der Stream-API | Abschnitt
Practice
Projects
Quizzes & Challenges
Quizze
Challenges
/
Stream-API in Java

bookLeistung in der Stream-API

Swipe um das Menü anzuzeigen

Sie haben den Code erfolgreich umgestaltet und ihn übersichtlicher, kürzer und ausdrucksstärker gemacht. Aber wie sieht es mit der Leistung aus? Wie effizient ist die Stream-API im Vergleich zu herkömmlichen Schleifen? Lässt sich die Ausführung mit parallelStream() beschleunigen? Finden wir es heraus!

Ausführungsgeschwindigkeit messen

Um die Leistung objektiv zu vergleichen, erstellen wir einen Testdatensatz mit 100.000 Benutzern und unterschiedlichen Bestellungen. Anschließend implementieren wir drei Filtermethoden:

  • Traditionelle for-loop – klassischer Ansatz mit verschachtelten Schleifen;
  • Stream-API (stream()) – moderne deklarative Methode;
  • Parallele Stream-API (parallelStream()) – mehrfädige Verarbeitung.

Die Ausführungszeit wird mit System.nanoTime() gemessen, das hochpräzise Zeitdifferenzen liefert.

Testimplementierung

Sie generieren 100.000 Benutzer, wobei sichergestellt wird, dass alle Bestellungen über $10.000 liegen, und führen alle drei Methoden aus, um die beste Leistung zu ermitteln.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
package com.example; import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<User> users = generateUsers(100000); // Measuring traditional loop execution time long startTime = System.nanoTime(); List<User> premiumUsersLoop = new ArrayList<>(); for (User user : users) { if (user.isActive()) { int totalOrders = 0; for (Order order : user.getOrders()) { if (order.getTotal() >= 10000) { totalOrders++; } } if (totalOrders >= 3) { premiumUsersLoop.add(user); } } } long endTime = System.nanoTime(); System.out.println("For-loop: " + (endTime - startTime) / 1_000_000 + " ms"); // Measuring Stream API execution time startTime = System.nanoTime(); List<User> premiumUsersStream = users.stream() .filter(User::isActive) .filter(user -> user.getOrders().stream() .filter(order -> order.getTotal() >= 10000) .count() >= 3) .toList(); endTime = System.nanoTime(); System.out.println("Stream API: " + (endTime - startTime) / 1_000_000 + " ms"); // Measuring Parallel Stream API execution time startTime = System.nanoTime(); List<User> premiumUsersParallelStream = users.parallelStream() .filter(User::isActive) .filter(user -> user.getOrders().stream() .filter(order -> order.getTotal() >= 10000) .count() >= 3) .toList(); endTime = System.nanoTime(); System.out.println("Parallel Stream API: " + (endTime - startTime) / 1_000_000 + " ms"); } private static List<User> generateUsers(int count) { List<User> users = new ArrayList<>(); for (int i = 0; i < count; i++) { users.add(new User("User" + i, true, List.of( new Order(14000), new Order(5000), new Order(7000) ))); } return users; } } class Order { private final double total; public Order(double total) { this.total = total; } public double getTotal() { return total; } } class User { private final String name; private final boolean active; private final List<Order> orders; public User(String name, boolean active, List<Order> orders) { this.name = name; this.active = active; this.orders = orders; } public boolean isActive() { return active; } public List<Order> getOrders() { return orders; } @Override public String toString() { return "User{name='" + name + "'}"; } }

Nach dem Ausführen des Tests mit 100.000 Benutzern lassen sich folgende Tendenzen beobachten:

Die traditionelle for-loop ist bei einfachen Operationen schneller, da sie keinen Overhead durch die Erstellung von Streams und zusätzlichen Objekten verursacht. Sie erzielt die besten Ergebnisse, wenn maximale Geschwindigkeit im Vordergrund steht.

Die Stream-API ist aufgrund zusätzlicher Stream-Objekte manchmal etwas langsamer, verbessert jedoch die Lesbarkeit und Wartbarkeit des Codes erheblich.

Die Parallel Stream-API kann die Verarbeitung auf Mehrkernsystemen beschleunigen, aber nicht immer. Ist der Datensatz klein, kann der Overhead für das Thread-Management die Ausführung sogar verlangsamen. Sie eignet sich am besten für rechenintensive Aufgaben, jedoch nicht, wenn gemeinsam genutzte Variablen verändert werden, da die Threads unabhängig voneinander laufen.

Zusammenfassung

Die Stream-API ist ein leistungsstarkes Werkzeug, das Code lesbarer und kürzer macht. Hinsichtlich der Performance ist es jedoch wichtig, ihre Einschränkungen zu verstehen. In manchen Fällen sind traditionelle for-Schleifen schneller, insbesondere bei kleinen Datensätzen. parallelStream() kann die Verarbeitungsgeschwindigkeit erhöhen, erfordert jedoch Tests, um sicherzustellen, dass tatsächlich ein Vorteil entsteht.

Die Wahl des richtigen Ansatzes sollte daher bewusst erfolgen: Wenn Lesbarkeit im Vordergrund steht, die Stream-API verwenden; wenn Performance entscheidend ist, testen und messen!

1. Welcher Ansatz ist für einfache Operationen typischerweise am schnellsten?

2. Warum kann die Stream-API langsamer sein als eine normale Schleife?

3. Wann kann parallelStream() die Ausführung verlangsamen?

question mark

Welcher Ansatz ist für einfache Operationen typischerweise am schnellsten?

Select the correct answer

question mark

Warum kann die Stream-API langsamer sein als eine normale Schleife?

Select the correct answer

question mark

Wann kann parallelStream() die Ausführung verlangsamen?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 1. Kapitel 41

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Abschnitt 1. Kapitel 41
some-alt