Java Academy · Les

Dead-code elimination vermijden

Blackhole en state

Les 4 van 413 stappen

Dead-code elimination vermijden is een gratis Java Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.

Verwijdering van dode code voorkomen

De grootste valkuil van microbenchmarks is verwijdering van dode code (DCE): als de JIT bewijst dat een resultaat nooit wordt gebruikt, verwijdert deze de berekening. Je benchmark meet dan niets. JMH geeft je twee hulpmiddelen om dit te voorkomen — waarden retourneren en de Blackhole.

De DCE-valkuil

Deze lus berekent een miljoen keer een vierkantswortel, maar gebruikt het resultaat nooit. Een slimme compiler kan de hele lus verwijderen.

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));
    }
}

Oplossing 1: het resultaat retourneren

De eenvoudigste verdediging is de berekende waarde te retourneren vanuit de methode met @Benchmark. JMH verwerkt elke geretourneerde waarde, dus de JVM kan niet bewijzen dat deze ongebruikt is.

import org.openjdk.jmh.annotations.Benchmark;

public class Bench {
    @Benchmark
    public double sqrt() {
        return Math.sqrt(42.0); // returned -> consumed by JMH
    }
}

Oplossing 2: de Blackhole

Wanneer een benchmark meerdere waarden oplevert of je er geen kunt retourneren, geef je een Blackhole mee en roep je consume(...) aan. De Blackhole overtuigt de JIT ervan dat elke waarde wordt gebruikt, zonder de kosten van echte bewerkingen.

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-objecten

Een klasse met @State bevat invoerwaarden die ondoorzichtig zijn voor de optimaliseerder, zodat het vooraf berekenen van constanten wordt voorkomen. JMH maakt hiervan een instantie en geeft die aan je benchmark door. Het bereik kan Thread, Benchmark (gedeeld) of Group zijn.

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 en @TearDown

Binnen een klasse met @State worden methoden met de annotatie @Setup vóór de meting uitgevoerd en methoden met @TearDown erna. Het Level bepaalt de frequentie: Trial (eenmalig), Iteration of 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;
    }
}

Vermijd constante invoer

Geef nooit letterlijke constanten door aan de methode die je test. Math.sqrt(2.0) kan tot een constante worden teruggebracht; Math.sqrt(state.value) kan dat niet. Haal invoer altijd uit een veld van @State.

Meerdere waarden retourneren

Als je benchmark vanzelf twee resultaten oplevert, kun je het ene retourneren en het andere via een Blackhole verbruiken, of ze combineren. Als een van beide niet wordt verbruikt, ontstaat het DCE-gat opnieuw.

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;
    }
}

Overhead van Blackhole

Blackhole is ontworpen om extreem weinig overhead te hebben en zelf bestand te zijn tegen optimalisatie, maar het is niet helemaal gratis. Geef bij ultrasnelle bewerkingen de voorkeur aan het retourneren van één waarde; gebruik Blackhole voor lussen en gevallen met meerdere waarden.

Controleer je metingen

Als een benchmark een onwaarschijnlijk lage tijd rapporteert (minder dan een nanoseconde voor echt werk), vermoed dan DCE of het terugbrengen tot een constante. Controleer opnieuw of resultaten worden geretourneerd of verbruikt en of de invoer uit @State komt.

Alles samenbrengen

Een robuuste benchmark leest invoer uit een object van @State, voert het werk uit en retourneert het resultaat met return of verbruikt het met Blackhole.consume. Met die drie gewoonten kunnen DCE en het terugbrengen tot een constante je metingen niet vervormen.

Korte controle

Test je begrip van het tegengaan van het verwijderen van dode code.

Samenvatting

Je hebt geleerd hoe je benchmarks betrouwbaar houdt:

  • Het verwijderen van dode code verwijdert ongebruikte berekeningen.
  • Retourneer één resultaat zodat JMH het verbruikt.
  • Gebruik Blackhole.consume voor lussen en meerdere waarden.
  • Objecten van @State houden invoer ondoorzichtig en voorkomen dat deze tot constanten wordt teruggebracht.
  • @Setup / @TearDown bereiden de toestand voor en ruimen deze op bij een gekozen Level.
Gratis beginnen

Leer Java met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
104
Lessen
374

Veelgestelde vragen

Is de les “Dead-code elimination vermijden” gratis?

Ja — de volledige tekst van “Dead-code elimination vermijden” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.

Wat leer ik in “Dead-code elimination vermijden”?

Blackhole en state Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Java Academy te beginnen?

Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Dead-code elimination vermijden”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Java Academy?

Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Waarom JMH
  2. Een benchmark schrijven
  3. Opwarmen en iteraties
  4. Dead-code elimination vermijden
← Terug naar Java Academy