Kuolleen koodin poiston estäminen
Blackhole ja tila.
Kuolleen koodin poiston estäminen on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Kuolleen koodin eliminoinnin välttäminen
Mikrobenchmarkin suurin yksittäinen sudenkuoppa on kuolleen koodin eliminointi (DCE): jos JIT pystyy todistamaan, ettei tulosta käytetä koskaan, se poistaa laskutoimituksen. Tällöin benchmark mittaa tyhjää. JMH tarjoaa kaksi työkalua tämän estämiseen — arvojen palauttamisen ja Blackhole-olion.
DCE-sudenkuoppa
Tämä silmukka laskee neliöjuuren miljoona kertaa, mutta ei koskaan käytä tulosta. Älykäs kääntäjä voi poistaa koko silmukan.
public class Main {
public static void main(String[] args) {
long t = System.nanoTime();
for (int i = 0; i < 1_000_000; i++) {
double ignored = Math.sqrt(i); // result thrown away
}
System.out.println("ns: " + (System.nanoTime() - t));
}
}Korjaus 1: Palauta tulos
Helpoin suojaus on palauttaa laskettu arvo @Benchmark-metodista. JMH kuluttaa jokaisen palautetun arvon, joten JVM ei voi todistaa sitä kuolleeksi.
import org.openjdk.jmh.annotations.Benchmark;
public class Bench {
@Benchmark
public double sqrt() {
return Math.sqrt(42.0); // returned -> consumed by JMH
}
}Korjaus 2: Blackhole
Kun benchmark tuottaa useita arvoja tai ette voi palauttaa yhtä arvoa, välittäkää sille Blackhole ja kutsukaa metodia consume(...). Blackhole saa JIT:n olettamaan, että jokaista arvoa käytetään, ilman todellisen työn kustannuksia.
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.infra.Blackhole;
public class Bench {
@Benchmark
public void manyValues(Blackhole bh) {
for (int i = 0; i < 100; i++) {
bh.consume(Math.sqrt(i));
}
}
}@State-oliot
@State-luokka sisältää syötteitä, jotka ovat optimoijalle läpinäkymättömiä ja estävät vakioiden esilaskennan. JMH luo olion ja välittää sen benchmarkille. Laajuus voi olla Thread, Benchmark (jaettu) tai Group.
import org.openjdk.jmh.annotations.*;
public class Bench {
@State(Scope.Thread)
public static class Data {
public int x = 21;
}
@Benchmark
public int multiply(Data d) {
return d.x * 2; // d.x is not a compile-time constant
}
}@Setup ja @TearDown
@State-luokan sisällä metodit, jotka on merkitty annotaatiolla @Setup, suoritetaan ennen mittausta ja annotaatiolla @TearDown merkityt metodit sen jälkeen. Level määrittää suoritusvälin: Trial (kerran), Iteration tai Invocation.
import org.openjdk.jmh.annotations.*;
@State(Scope.Thread)
public class Data {
int[] arr;
@Setup(Level.Trial)
public void init() {
arr = new int[1000];
for (int i = 0; i < arr.length; i++) arr[i] = i;
}
}Välttäkää vakioarvoisia syötteitä
Älkää koskaan välittäkö testattavalle metodille literaalivakioita. Math.sqrt(2.0) voidaan sieventää vakioksi, mutta Math.sqrt(state.value) ei. Hakekaa syötteet aina @State-kentästä.
Usean arvon palauttaminen
Jos benchmark tuottaa luonnostaan kaksi tulosta, voitte palauttaa toisen ja kuluttaa toisen Blackholen kautta tai yhdistää tulokset. Jos jompikumpi jää kuluttamatta, DCE voi jälleen poistaa laskennan.
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.infra.Blackhole;
public class Bench {
@Benchmark
public int twoResults(Blackhole bh) {
int a = 3 * 7;
int b = 5 + 9;
bh.consume(b);
return a;
}
}Blackholen lisäkustannus
Blackhole on suunniteltu erittäin kevyeksi ja itsessään optimointia kestäväksi, mutta se ei ole täysin ilmainen. Erittäin nopeissa operaatioissa palauttakaa mieluummin yksi arvo; käyttäkää Blackholea silmukoissa ja usean arvon tapauksissa.
Tarkistakaa lukujen järkevyys
Jos benchmark raportoi mahdottoman pienen ajan, kuten alle nanosekunnin todelliselle työlle, epäilkää DCE:tä tai vakioarvojen sieventämistä. Tarkistakaa uudelleen, että tulokset palautetaan tai kulutetaan ja että syötteet tulevat @State-kentästä.
Kootaan kaikki yhteen
Luotettava benchmark lukee syötteet @State-objektista, suorittaa työn ja joko returntaa tuloksen tai kuluttaa sen kutsulla Blackhole.consume. Näiden kolmen tavan avulla DCE ja vakioarvojen sieventäminen eivät voi vääristää mittaustuloksia.
Pikatarkistus
Testatkaa, miten hyvin ymmärrätte kuolleen koodin eliminoinnin estämisen.
Kertaus
Opitte pitämään benchmarkit luotettavina:
- Kuolleen koodin eliminointi poistaa käyttämättömät laskennat.
- Palauttakaa yksi tulos, jotta JMH kuluttaa sen.
- Käyttäkää Blackhole.consume-kutsua silmukoissa ja usean arvon tapauksissa.
- @State-objektit pitävät syötteet epäselvinä ja estävät vakioarvojen sieventämisen.
- @Setup / @TearDown valmistelevat ja siivoavat tilan valitulla Level-tasolla.
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”Kuolleen koodin poiston estäminen” ilmainen?
Kyllä – oppitunnin ”Kuolleen koodin poiston estäminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Kuolleen koodin poiston estäminen”?
Blackhole ja tila. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Kuolleen koodin poiston estäminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Miksi JMH
- Vertailutestin kirjoittaminen
- Lämmitys ja iteraatiot
- Kuolleen koodin poiston estäminen