Når parallellitet hjelper
Arbeidsmengde og datastørrelse
Når parallellitet hjelper er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.
Parallellitet har en kostnad
Parallell utførelse gir ekstra kostnader: data må deles opp, oppgaver sendes ut og resultater slås sammen. Det lønner seg bare når denne kostnaden er mindre enn tiden som spares.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long sum = IntStream.rangeClosed(1, 10_000_000)
.parallel()
.asLongStream()
.sum();
System.out.println(sum);
}
}Faktor 1: Datastørrelse (N)
En stor N fordeler parallellitetens faste kostnader over flere elementer. En grov tommelfingerregel er at det trengs titusenvis av elementer før parallell utførelse lønner seg.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long count = IntStream.rangeClosed(1, 5_000_000)
.parallel()
.filter(n -> n % 7 == 0)
.count();
System.out.println(count);
}
}Faktor 2: Arbeid per element (Q)
Kostnaden Q ved å behandle hvert element har betydning. Kostbart arbeid per element (tunge beregninger) får fordel av parallellitet selv ved mindre N.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long primes = IntStream.rangeClosed(2, 200_000)
.parallel()
.filter(Main::isPrime)
.count();
System.out.println(primes);
}
static boolean isPrime(int n) {
for (int i = 2; (long) i * i <= n; i++)
if (n % i == 0) return false;
return true;
}
}Intuisjonen bak N ganger Q
Tenk på det totale nyttige arbeidet som N x Q. Jo større dette produktet er, desto mer kan parallellitet hjelpe. En liten N eller en triviell Q rettferdiggjør det sjelden.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
double sum = IntStream.rangeClosed(1, 1_000_000)
.parallel()
.mapToDouble(n -> Math.sqrt(n) * Math.log(n + 1))
.sum();
System.out.println(sum);
}
}Faktor 3: Mulighet for oppdeling
Datakilder som kan deles opp billig og jevnt, egner seg godt for parallell utførelse: tabeller, ArrayList og IntStream.range. LinkedList og iteratorbaserte kilder egner seg dårlig til oppdeling.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1_000_000; i++) list.add(i);
long even = list.parallelStream().filter(n -> n % 2 == 0).count();
System.out.println(even);
}
}God kilde: tabeller og intervaller
Primitive intervaller har kjent størrelse og kan deles opp i O(1), noe som gjør dem til ideelle parallelle kilder.
import java.util.stream.LongStream;
public class Main {
public static void main(String[] args) {
long sum = LongStream.rangeClosed(1, 20_000_000)
.parallel()
.sum();
System.out.println(sum);
}
}Dårlig kilde: iterative generatorer
Stream.iterate produserer elementer sekvensielt per definisjon, så strømmen kan ikke deles opp før elementene er realisert. Den er derfor en svak parallell kilde.
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
long count = Stream.iterate(1, n -> n + 1)
.limit(1_000_000)
.parallel()
.filter(n -> n % 2 == 0)
.count();
System.out.println(count);
}
}Faktor 4: Rimelig sammenslåing
Parallellitet krever en rimelig måte å kombinere delresultater på. sum og count kan slås sammen trivielt; å bygge en sortert liste eller bruke en trebasert samler gjør sammenslåingen kostbar.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int max = IntStream.rangeClosed(1, 5_000_000)
.parallel()
.map(n -> n % 1000)
.max()
.getAsInt();
System.out.println(max);
}
}Unngå dette ved I/O-bundet arbeid
Parallelle strømmer er beregnet på CPU-bundne oppgaver i fork-join-poolen. Blokkerende I/O sulter den delte poolen for tråder og skader hele applikasjonen. Bruk dedikerte eksekutorer for I/O i stedet.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long total = IntStream.rangeClosed(1, 1_000_000)
.parallel()
.mapToLong(n -> (long) n * n)
.sum();
System.out.println(total);
}
}Mål, ikke gjett
Den eneste pålitelige måten å vite om parallellitet hjelper, er å benchmarke med realistiske data. Intuisjon om ytelse er ofte feil.
import java.util.stream.LongStream;
public class Main {
public static void main(String[] args) {
long start = System.nanoTime();
long sum = LongStream.rangeClosed(1, 50_000_000).parallel().sum();
long ms = (System.nanoTime() - start) / 1_000_000;
System.out.println("sum=" + sum + " took ~" + ms + "ms");
}
}En praktisk sjekkliste
Foretrekk parallell utførelse når alt dette gjelder:
- Stor N og/eller kostbart arbeid per element.
- En kilde som kan deles opp (tabell, ArrayList, intervall).
- En rimelig og assosiativ sammenslåing.
- CPU-bundet arbeid uten blokkerende I/O.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
double avg = IntStream.rangeClosed(1, 10_000_000)
.parallel()
.mapToDouble(Math::sqrt)
.average()
.getAsDouble();
System.out.println(avg);
}
}Rask kontroll
Hvilket scenario egner seg best for en parallell strøm?
Oppsummering
De har lært når parallellitet hjelper:
- Fordelen øker med N x Q (datastørrelse multiplisert med kostnaden per element).
- Det trengs en kilde som kan deles opp (tabeller, ArrayList, intervaller).
- Det trengs en rimelig og assosiativ sammenslåing.
- Hold arbeidet CPU-bundet, unngå blokkerende I/O, og mål alltid.
Lær deg Java med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 104
- Leksjoner
- 374
Ofte stilte spørsmål
Er leksjonen «Når parallellitet hjelper» gratis?
Ja – hele teksten i «Når parallellitet hjelper» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Når parallellitet hjelper»?
Arbeidsmengde og datastørrelse Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Java Academy?
Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Når parallellitet hjelper»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?
Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Opprette parallelle strømmer
- Når parallellitet hjelper
- Trådsikkerhet og bivirkninger
- Vanlige fallgruver