Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Prestanda i Stream API | Praktiska Tillämpningar av Stream API
Stream API

bookPrestanda i Stream API

Du har framgångsrikt refaktorerat koden, vilket gör den renare, kortare och mer uttrycksfull. Men hur är det med prestanda? Hur effektiv är Stream API jämfört med traditionella loopar? Kan du öka hastigheten med parallelStream()? Låt oss ta reda på det!

Mäta exekveringstid

För att objektivt jämföra prestanda kommer vi att skapa en testdatamängd med 100 000 användare och olika ordrar. Därefter implementeras tre filtreringsmetoder:

  • Traditionell for-loop – ett klassiskt tillvägagångssätt med nästlade loopar;
  • Stream API (stream()) – en modern deklarativ metod;
  • Parallel Stream API (parallelStream()) – multitrådad bearbetning.

Du mäter exekveringstid med hjälp av System.nanoTime(), vilket ger högprecisions-tidsdifferenser.

Testimplementering

Du genererar 100 000 användare, säkerställer att de alla har ordrar över $10,000, och kör alla tre metoder för att se vilken som presterar bäst.

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

Efter att ha kört testet med 100 000 användare kan du observera följande tendenser:

Traditionell for-loop är snabbare för enkla operationer eftersom den undviker overhead från skapandet av strömmar och ytterligare objekt. Den presterar bäst när rå hastighet är prioriterad.

Stream API är ibland något långsammare på grund av extra strömobjekt, men förbättrar avsevärt kodläsbarhet och underhållbarhet.

Parallel Stream API kan snabba upp bearbetningenflerkärniga system, men inte alltid. Om datamängden är liten kan overheaden för trådhantering faktiskt sakta ner processen. Det fungerar bäst för tunga beräkningar, men inte när man modifierar delade variabler, eftersom trådarna körs oberoende.

Sammanfattning

Stream API är ett kraftfullt verktyg som gör koden mer lättläst och koncis. När det gäller prestanda är det dock viktigt att förstå dess begränsningar. I vissa fall är traditionella for-loopar snabbare, särskilt vid arbete med små datamängder. parallelStream() kan förbättra bearbetningshastigheten, men det kräver testning för att säkerställa att det faktiskt ger en fördel.

Att välja rätt tillvägagångssätt bör därför vara avsiktligt: om läsbarhet är en prioritet, använd Stream API; om prestanda är avgörande, testa och mät!

1. Vilket tillvägagångssätt är vanligtvis snabbast för enkla operationer?

2. Varför kan Stream API vara långsammare än en vanlig loop?

3. När kan parallelStream() göra exekveringen långsammare?

question mark

Vilket tillvägagångssätt är vanligtvis snabbast för enkla operationer?

Select the correct answer

question mark

Varför kan Stream API vara långsammare än en vanlig loop?

Select the correct answer

question mark

När kan parallelStream() göra exekveringen långsammare?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 2

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Awesome!

Completion rate improved to 2.33

bookPrestanda i Stream API

Svep för att visa menyn

Du har framgångsrikt refaktorerat koden, vilket gör den renare, kortare och mer uttrycksfull. Men hur är det med prestanda? Hur effektiv är Stream API jämfört med traditionella loopar? Kan du öka hastigheten med parallelStream()? Låt oss ta reda på det!

Mäta exekveringstid

För att objektivt jämföra prestanda kommer vi att skapa en testdatamängd med 100 000 användare och olika ordrar. Därefter implementeras tre filtreringsmetoder:

  • Traditionell for-loop – ett klassiskt tillvägagångssätt med nästlade loopar;
  • Stream API (stream()) – en modern deklarativ metod;
  • Parallel Stream API (parallelStream()) – multitrådad bearbetning.

Du mäter exekveringstid med hjälp av System.nanoTime(), vilket ger högprecisions-tidsdifferenser.

Testimplementering

Du genererar 100 000 användare, säkerställer att de alla har ordrar över $10,000, och kör alla tre metoder för att se vilken som presterar bäst.

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

Efter att ha kört testet med 100 000 användare kan du observera följande tendenser:

Traditionell for-loop är snabbare för enkla operationer eftersom den undviker overhead från skapandet av strömmar och ytterligare objekt. Den presterar bäst när rå hastighet är prioriterad.

Stream API är ibland något långsammare på grund av extra strömobjekt, men förbättrar avsevärt kodläsbarhet och underhållbarhet.

Parallel Stream API kan snabba upp bearbetningenflerkärniga system, men inte alltid. Om datamängden är liten kan overheaden för trådhantering faktiskt sakta ner processen. Det fungerar bäst för tunga beräkningar, men inte när man modifierar delade variabler, eftersom trådarna körs oberoende.

Sammanfattning

Stream API är ett kraftfullt verktyg som gör koden mer lättläst och koncis. När det gäller prestanda är det dock viktigt att förstå dess begränsningar. I vissa fall är traditionella for-loopar snabbare, särskilt vid arbete med små datamängder. parallelStream() kan förbättra bearbetningshastigheten, men det kräver testning för att säkerställa att det faktiskt ger en fördel.

Att välja rätt tillvägagångssätt bör därför vara avsiktligt: om läsbarhet är en prioritet, använd Stream API; om prestanda är avgörande, testa och mät!

1. Vilket tillvägagångssätt är vanligtvis snabbast för enkla operationer?

2. Varför kan Stream API vara långsammare än en vanlig loop?

3. När kan parallelStream() göra exekveringen långsammare?

question mark

Vilket tillvägagångssätt är vanligtvis snabbast för enkla operationer?

Select the correct answer

question mark

Varför kan Stream API vara långsammare än en vanlig loop?

Select the correct answer

question mark

När kan parallelStream() göra exekveringen långsammare?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 2
some-alt