Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Suorituskyky Stream API:ssa | Osio
Practice
Projects
Quizzes & Challenges
Visat
Challenges
/
Stream API Javassa

bookSuorituskyky Stream API:ssa

Pyyhkäise näyttääksesi valikon

Olet onnistuneesti refaktoroinut koodin, tehden siitä selkeämmän, lyhyemmän ja ilmaisullisemman. Mutta entä suorituskyky? Kuinka tehokas Stream API on verrattuna perinteisiin silmukoihin? Voiko parallelStream() nopeuttaa sitä? Otetaan selvää!

Suorituksen ajan mittaaminen

Objektiivisen suorituskyvyn vertailun vuoksi luodaan testiaineisto, jossa on 100 000 käyttäjää ja erilaisia tilauksia. Toteutetaan kolme suodatustapaa:

  • Perinteinen for-loop – klassinen ratkaisu sisäkkäisillä silmukoilla;
  • Stream API (stream()) – moderni deklaratiivinen menetelmä;
  • Parallel Stream API (parallelStream()) – monisäikeinen käsittely.

Suoritusaika mitataan käyttäen System.nanoTime(), joka tarjoaa tarkan aikamittauksen.

Testin toteutus

Luodaan 100 000 käyttäjää, joilla kaikilla on yli 10 000 dollarin tilaukset, ja ajetaan kaikki kolme menetelmää nähdäksemme, mikä niistä on tehokkain.

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

Suoritettaessa testiä 100 000 käyttäjällä voidaan havaita seuraavia suuntauksia:

Perinteinen for-loop on nopeampi yksinkertaisissa operaatioissa, koska se välttää streamin luonnista ja ylimääräisistä olioista aiheutuvan ylikuorman. Se suoriutuu parhaiten, kun raaka nopeus on ensisijainen tavoite.

Stream API on joskus hieman hitaampi ylimääräisten stream-olioiden vuoksi, mutta se parantaa merkittävästi koodin luettavuutta ja ylläpidettävyyttä.

Rinnakkaisella Stream API:lla voidaan nopeuttaa käsittelyä moniydinkoneilla, mutta ei aina. Jos aineisto on pieni, säikeiden hallinnasta aiheutuva ylikuorma voi itse asiassa hidastaa toimintaa. Se soveltuu parhaiten raskaisiin laskentatehtäviin, mutta ei silloin, kun jaettuja muuttujia muokataan, koska säikeet toimivat itsenäisesti.

Yhteenveto

Stream API on tehokas työkalu, joka tekee koodista luettavampaa ja ytimekkäämpää. Kuitenkin suorituskyvyn osalta on tärkeää ymmärtää sen rajoitukset. Joissakin tapauksissa perinteiset for-silmukat ovat nopeampia, erityisesti pienten tietoaineistojen kanssa työskenneltäessä. parallelStream() voi parantaa käsittelynopeutta, mutta sen hyöty tulee varmistaa testaamalla.

Oikean lähestymistavan valinta tulee tehdä tarkoituksellisesti: jos luettavuus on etusijalla, käytä Stream APIa; jos suorituskyky on kriittistä, testaa ja mittaa!

1. Mikä lähestymistapa on tyypillisesti nopein yksinkertaisissa operaatioissa?

2. Miksi Stream API voi olla hitaampi kuin tavallinen silmukka?

3. Milloin parallelStream() voi hidastaa suoritusta?

question mark

Mikä lähestymistapa on tyypillisesti nopein yksinkertaisissa operaatioissa?

Select the correct answer

question mark

Miksi Stream API voi olla hitaampi kuin tavallinen silmukka?

Select the correct answer

question mark

Milloin parallelStream() voi hidastaa suoritusta?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 41

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Osio 1. Luku 41
some-alt