Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Prestaties in Stream API | Praktische Toepassingen van Stream API
Stream-API

bookPrestaties in Stream API

Je hebt de code succesvol gerefactord, waardoor deze netter, korter en meer expressief is geworden. Maar hoe zit het met de prestaties? Hoe efficiënt is de Stream API vergeleken met traditionele lussen? Kun je het versnellen met parallelStream()? Laten we het ontdekken!

Uitvoertijd meten

Om de prestaties objectief te vergelijken, maken we een testdataset met 100.000 gebruikers en verschillende bestellingen. Vervolgens implementeren we drie filtermethoden:

  • Traditionele for-loop – een klassieke aanpak met geneste lussen;
  • Stream API (stream()) – een moderne declaratieve methode;
  • Parallel Stream API (parallelStream()) – multithreaded verwerking.

Je meet de uitvoertijd met System.nanoTime(), dat nauwkeurige tijdsverschillen biedt.

Testimplementatie

Je genereert 100.000 gebruikers, waarbij je ervoor zorgt dat ze allemaal bestellingen boven de $10.000 hebben, en voert alle drie de methoden uit om te zien welke het beste presteert.

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 + "'}"; } }

Na het uitvoeren van de test met 100.000 gebruikers, kunnen de volgende trends worden waargenomen:

De traditionele for-loop is sneller bij eenvoudige bewerkingen omdat deze geen overhead heeft van stream-creatie en extra objecten. Dit levert de beste prestaties wanneer ruwe snelheid prioriteit heeft.

De Stream API is soms iets trager door extra stream-objecten, maar verbetert aanzienlijk de leesbaarheid en onderhoudbaarheid van de code.

De Parallel Stream API kan de verwerking versnellen op multi-core systemen, maar niet altijd. Als de dataset klein is, kan de overhead van threadbeheer het juist vertragen. Dit werkt het beste bij zware berekeningen, maar niet bij het wijzigen van gedeelde variabelen, omdat threads onafhankelijk van elkaar draaien.

Samenvatting

Stream API is een krachtig hulpmiddel dat code leesbaarder en bondiger maakt. Echter, als het gaat om prestaties, is het belangrijk om de beperkingen te begrijpen. In sommige gevallen zijn traditionele for-loops sneller, vooral bij het werken met kleine datasets. parallelStream() kan de verwerkingssnelheid verhogen, maar vereist testen om te verzekeren dat het daadwerkelijk een voordeel oplevert.

Het kiezen van de juiste aanpak moet dus bewust gebeuren: als leesbaarheid prioriteit heeft, gebruik dan de Stream API; als prestaties cruciaal zijn, test en meet!

1. Welke aanpak is doorgaans het snelst voor eenvoudige bewerkingen?

2. Waarom kan Stream API langzamer zijn dan een gewone lus?

3. Wanneer kan parallelStream() de uitvoering vertragen?

question mark

Welke aanpak is doorgaans het snelst voor eenvoudige bewerkingen?

Select the correct answer

question mark

Waarom kan Stream API langzamer zijn dan een gewone lus?

Select the correct answer

question mark

Wanneer kan parallelStream() de uitvoering vertragen?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 4. Hoofdstuk 2

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

Awesome!

Completion rate improved to 2.33

bookPrestaties in Stream API

Veeg om het menu te tonen

Je hebt de code succesvol gerefactord, waardoor deze netter, korter en meer expressief is geworden. Maar hoe zit het met de prestaties? Hoe efficiënt is de Stream API vergeleken met traditionele lussen? Kun je het versnellen met parallelStream()? Laten we het ontdekken!

Uitvoertijd meten

Om de prestaties objectief te vergelijken, maken we een testdataset met 100.000 gebruikers en verschillende bestellingen. Vervolgens implementeren we drie filtermethoden:

  • Traditionele for-loop – een klassieke aanpak met geneste lussen;
  • Stream API (stream()) – een moderne declaratieve methode;
  • Parallel Stream API (parallelStream()) – multithreaded verwerking.

Je meet de uitvoertijd met System.nanoTime(), dat nauwkeurige tijdsverschillen biedt.

Testimplementatie

Je genereert 100.000 gebruikers, waarbij je ervoor zorgt dat ze allemaal bestellingen boven de $10.000 hebben, en voert alle drie de methoden uit om te zien welke het beste presteert.

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 + "'}"; } }

Na het uitvoeren van de test met 100.000 gebruikers, kunnen de volgende trends worden waargenomen:

De traditionele for-loop is sneller bij eenvoudige bewerkingen omdat deze geen overhead heeft van stream-creatie en extra objecten. Dit levert de beste prestaties wanneer ruwe snelheid prioriteit heeft.

De Stream API is soms iets trager door extra stream-objecten, maar verbetert aanzienlijk de leesbaarheid en onderhoudbaarheid van de code.

De Parallel Stream API kan de verwerking versnellen op multi-core systemen, maar niet altijd. Als de dataset klein is, kan de overhead van threadbeheer het juist vertragen. Dit werkt het beste bij zware berekeningen, maar niet bij het wijzigen van gedeelde variabelen, omdat threads onafhankelijk van elkaar draaien.

Samenvatting

Stream API is een krachtig hulpmiddel dat code leesbaarder en bondiger maakt. Echter, als het gaat om prestaties, is het belangrijk om de beperkingen te begrijpen. In sommige gevallen zijn traditionele for-loops sneller, vooral bij het werken met kleine datasets. parallelStream() kan de verwerkingssnelheid verhogen, maar vereist testen om te verzekeren dat het daadwerkelijk een voordeel oplevert.

Het kiezen van de juiste aanpak moet dus bewust gebeuren: als leesbaarheid prioriteit heeft, gebruik dan de Stream API; als prestaties cruciaal zijn, test en meet!

1. Welke aanpak is doorgaans het snelst voor eenvoudige bewerkingen?

2. Waarom kan Stream API langzamer zijn dan een gewone lus?

3. Wanneer kan parallelStream() de uitvoering vertragen?

question mark

Welke aanpak is doorgaans het snelst voor eenvoudige bewerkingen?

Select the correct answer

question mark

Waarom kan Stream API langzamer zijn dan een gewone lus?

Select the correct answer

question mark

Wanneer kan parallelStream() de uitvoering vertragen?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 4. Hoofdstuk 2
some-alt