Benchmarking mit dem JMH-Framework

Benchmarking unter Java hat mit einigen Problemen zu kämpfen. So optimiert die Java-Laufzeitumgebung den Quellcode, je nachdem wie oft er benutzt wird. Wenn nun kleinere Dinge getestet werden sollen, wie z.B. ob Methode A oder B besser funktioniert so wird dies problematisch. Am Anfang würde besagte Methoden nur interpretiert werden, anschließend würden sie bei häufiger Benutzung kompiliert werden und bei noch häufigerer Benutzung weiter optimiert werden. Daneben kann es passieren dass der Benchmark komplett wegoptimiert wird, da die JVM unter Umständen erkennt, dass die genutzten Werte bzw. die Ergebnisse des Benchmarks später nicht mehr genutzt werden.

Die offizielle Seite des Java Microbenchmark Harness-Framework

Damit sich ein Entwickler nicht immer und immer wieder mit solchen Problemen beim Benchmarking herumschlagen muss, wird seit einigen Jahren im Rahmen des OpenJDK-Projektes an dem Java Microbenchmark Harness-Framework gearbeitet. Das JMH-Framework nimmt dem Entwickler viele Aufgaben ab, um diese Probleme zu lösen. So kann bzw. wird die JVM durch JMH aufgewärmt werden und auch die Messung der Zeiten übernimmt JMH. Um JMH zu nutzen, müssen die entsprechenden Abhängigkeiten (in diesem Fall über die Maven-POM-Datei) dem Projekt hinzugefügt werden:

<dependency>
	<groupId>org.openjdk.jmh</groupId>
	<artifactId>jmh-core</artifactId>
	<version>1.21</version>
</dependency>
<dependency>
	<groupId>org.openjdk.jmh</groupId>
	<artifactId>jmh-generator-annprocess</artifactId>
	<version>1.21</version>
</dependency>

Sind die Abhängigkeiten eingebunden, kann mit dem eigentlichen Aufbau des Benchmarks begonnen werden. Jede Methode, welche ein Benchmark durchführen möchte, muss mit der @Benchmark-Annotation gekennzeichnet werden:

@Benchmark
public int addInts() {
    return aInt + bInt;
}

Die Klasse, in welcher die Benchmarks definiert sind, muss mit einigen weiteren Annotationen ausgestattet werden:

@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class AddingBenchmark {
...

Die @State(Scope.Benchmark)-Annotation in diesem Beispiel sorgt dafür das die Felder im Rahmen des Benchmarks für die Benchmark-Methoden zur Verfügung stehen. Mit der @BenchmarkMode-Annotation wird definiert, welche Art von Messung vorgenommen werden soll. In diesem Fall wird die durchschnittliche Zeit für eine einzelne Operation gemessen und ausgegeben. Über die @OutputTimeUnit-Annotation wird definiert wie die Zeiten für die Messungen ausgegeben werden. Werden für den Benchmark Daten benötigt so können sie über eine Methode, welche mit der @SetupAnnotation versehen wird, erzeugt werden:

@Setup
public void setup() {
    ...
}

Die setup-Methode wird damit vor dem eigentlichen Benchmark ausgeführt und somit können benötigte Daten dort erzeugt werden. Damit der Benchmark nun ausgeführt werden kann muss das Java Microbenchmark Harness-Framework angestartet werden. Dafür wird eine Klasse geschrieben und mit einer main-Methode versehen:

package net.seeseekey.JavaBenchmark;

import org.openjdk.jmh.runner.RunnerException;

import java.io.IOException;

public class Runner {

    public static void main(String[] args) throws IOException, RunnerException {
        
        org.openjdk.jmh.Main.main(args);
    }
}

Über die main-Methode wird die main-Methode des Frameworks gestartet und damit wird das Benchmark durchgeführt. Alternativ kann die Methode org.openjdk.jmh.Main.main auch direkt in der Maven-POM-Datei als Startklasse definiert werden:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>org.openjdk.jmh.Main.main</mainClass>
            </manifest>

Nachdem der Benchmark implementiert ist, kann dieser natürlich über die IDE ausgeführt werden. Das würde allerdings nicht ganz der Intention von JMH entsprechen. Stattdessen sollte eine JAR aus dem Projekt erzeugt werden und diese, auf einem möglichst unbelastetem System, über die Konsole ausgeführt werden:

java -jar benchmark.jar

Damit wird der Benchmark über JMH ausgeführt. JMH beginnt mit einer Warmup-Phase und führt anschließend den eigentlichen Benchmark durch. Nach einigen Minuten erhält der Entwickler die Auswertung des Benchmark:

Benchmark                                 Mode  Cnt   Score    Error  Units
JavaBenchmark.AddingBenchmark.addDoubles  avgt   25  ≈ 10⁻⁵           ms/op
JavaBenchmark.AddingBenchmark.addInts     avgt   25  ≈ 10⁻⁵           ms/op

In diesem Fall sieht der Entwickler bei der Ausgabe, dass die Ausgabeeinheit für die Zeit mit Millisekunden zu grob gewählt wurde und stattdessen besser Nanosekunden genutzt werden sollten.

Freie Einführung in JavaScript

Einführungen in JavaScript gibt es viele. Meist werden bestimmte Themen beleuchtet und dann ist die Einführung auch schon wieder vorbei. Die sich an Einsteiger richtende Einführung in JavaScript, welche unter molily.de/js/ zu finden ist, versucht alle essenziellen und wichtigen Themen rund um JavaScript zu beleuchten.

Die freie Einführung in JavaScript

Die Themen reichen von der Syntax von JavaScript, über die Einbindung zu fortgeschritteneren Themen, wie Browserübergreifende Entwicklung und Sicherheit im Kontext von JavaScript. Neben der Webseite sind die Quellen der Einführung auf GitHub zu finden. Lizenziert ist die Einführung unter der Creative Commons-Lizenz CC-BY-SA.

Nachkommastellen von Pi als REST-Service

Die Zahl Pi beschreibt das Verhältnis des Umfangs eines Kreises zu seinem Durchmesser und gehört sicherlich zu den bekannteren mathematischen Konstanten. Anlässlich des Pi-Days am 14. März 2019 veröffentlichte Google die Zahl Pi mit bisher unerreichten 31,4 Billionen Nachkommastellen.

3.1415926535897…

Passend dazu stellte Google die Seite pi.delivery in Netz. Neben einigen Spielereien rund um Pi, wie die Nutzung von Pi zur Generierung von Musik, findet sich dort eine REST-API, mit welcher die Nachkommastellen von Pi erfragt werden können. Ein einfacher Request des Services sieht wie folgt aus:

GET https://api.pi.delivery/v1/pi?start=0&numberOfDigits=42

Für den Request existieren zwei Parameter. Der erste Parameter mit dem Namen start definiert ab welcher Stelle die Nachkommastellen geliefert werden sollen. Der zweite Parameter numberOfDigits setzt die Anzahl der zurückgelieferten Nachkommastellen. Als Antwort erhält der Nutzer des Service anschließend die entsprechenden Nachkommastellen (sowie die 3 am Anfang von Pi):

{
    "content": "314159265358979323846264338327950288419716"
}

Datenbank der verhängten DSGVO-Bußgelder

Seit Einführung der Datenschutz-Grundverordnung bzw. der Gültigkeit derselben ist es europaweit möglich bei Verstößen gegen das entsprechende Recht Bußgelder zu verhängen. Mittlerweile wurden viele entsprechende Bußgelder verhangen.

enforcementtracker.com

Eine Übersicht der verhängten Bußgelder findet sich auf dem GDPR Enforcement Tracker, welcher unter enforcementtracker.com zu finden ist. Mittlerweile finden sich um die 25 Einträge in der Datenbank. Neben dem verhängten Bußgeld findet sich in der Datenbank die rechtliche Grundlage für das Bußgeld und eine Zusammenfassung des Sachverhaltes. Die Datenbasis für den GDPR Enforcement Tracker bilden öffentliche Daten, wie Zeitungsartikel oder entsprechende Berichte.

GameBoy-Adventures einfach entwickeln

Heute ist das dreißigjährige Jubiläum des GameBoy. Da wird der eine oder andere sicherlich nostalgisch an die gute alte Zeit zurückdenken. Nun kann auf dem GameBoy nicht nur gespielt werden was die Hersteller damals veröffentlichten, sondern auch eigene Entwicklungen für den GameBoy erstellt werden.

Das GB Studio unter macOS

Den meisten dürfte dies allerdings zu kompliziert sein. Schließlich ist der GameBoy aufgrund seiner begrenzten Ressourcen keine sonderlich einfache Umgebung. Mit dem GB Studio soll die Entwicklung trotzdem einfach möglich sein. Mithilfe des GB Studios ist es möglich grafische Adventure schnell und unkompliziert im Stil eines Game Makers zu erzeugen. Als Export-Formate werden ROMs und ein Web-Export unterstützt.

Das Spiele-ROM läuft im Emulator

Lizenziert ist GB Studio unter der MIT Lizenz. Da es auf Electron aufbaut, existieren Versionen für macOS, Linux und Windows. Der Quelltext des Projektes ist auf GitHub gehostet. Er ist unter der MIT-Lizenz lizenziert und damit freie Software. Die offizielle Seite des Projektes, auf der unter anderem die Dokumentation zu finden ist, ist unter gbstudio.dev zu finden.