Seit Java 16 gibt es das instanceOf pattern matching, das ich bislang einfach nur als Vereinfachung gesehen habe. Jetzt bin ich allerdings über diverse Inhalte gestoßen, von denen ich einigermaßen begeistert bin und die ich Euch nicht vorenthalten möchte.
Vorher aber kurz eine Erklärung, für diejenigen, die nicht wissen, worum es beim instanceOf pattern matching geht. Manchmal steht man vor dem Problem, dass man ein Objekt bekommt und prüfen muss, ob das Objekt eine Instanz eines bestimmten Typs ist, um anschließend mit den Methoden dieses Typs weiterarbeiten zu können.
Bis Java 15 waren hierfür drei Schritte notwendig.
Siet Java 16 kann man nun kurz schreiben:
Zurück zum eigentlichen Thema. Die equals-Methode wird üblicherweise ähnlich überschrieben, wie im folgenden Beispiel gezeigt:
Mit pattern matching kann man nun z. B. schreiben:
In dieser Art hat das Brian Goetz auch für das JDK committed. Klar, das ist kürzer und einfacher zu lesen. Der Knaller aber ist, dass der Spaß auch noch schneller ist (wobei das auch davon abhängt, womit man vergleicht):
(Edit / Hinweis: hier hat sich leider ein Fehler eingeschlichen - siehe #8 für Details bezüglich der Geschwindigkeit, die ungefähr gleich ist bei beiden Varianten)
Im JEP zum instanceOf pattern matching wird die equals-Methode gar in dieser Weise implementiert:
Das gefällt mir! Aber warum wird hier sogar völlig auf die Referenzvergleiche verzichtet? José Paumard hat darauf eine Antwort: predictive branching.
Die CPU macht Vorhersagen, welcher Zweig durchlaufen werden wird und kann so die Pipeline besser füllen. Stellt sich heraus, dass die Vorhersage falsch war (der Referenzvergleich muss ja in jedem Fall ausgeführt werden), muss zurückgesetzt werden - was im Verhältnis massig Zeit kostet. In Summe macht dies den Versuch der Optimierung über den Referenzvergleich oft zunichte.
Vorher aber kurz eine Erklärung, für diejenigen, die nicht wissen, worum es beim instanceOf pattern matching geht. Manchmal steht man vor dem Problem, dass man ein Objekt bekommt und prüfen muss, ob das Objekt eine Instanz eines bestimmten Typs ist, um anschließend mit den Methoden dieses Typs weiterarbeiten zu können.
Bis Java 15 waren hierfür drei Schritte notwendig.
- Prüfen, ob das gegebene Objekt eine Instanz des Typs ist.
- Falls ja, das Objekt auf den betreffenden Typ casten und
- einer mit diesem Typ deklarierten, lokalen Variablen zuweisen.
Java:
if (obj instanceOf Typ) {
Typ instanz = (Typ) obj;
// mach was mit instanz
}
Siet Java 16 kann man nun kurz schreiben:
Java:
if (obj instanceof Typ instanz) {
// mach was mit instanz
}
Zurück zum eigentlichen Thema. Die equals-Methode wird üblicherweise ähnlich überschrieben, wie im folgenden Beispiel gezeigt:
Java:
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null) return false;
if (!(obj instanceof Typ)) return false;
Typ other = (Typ) obj;
return this.x == other.x
&& this.y == other.y;
}
Mit pattern matching kann man nun z. B. schreiben:
Java:
public boolean equals(Object obj) {
if (this == obj) return true;
return (obj instanceof Typ other)
&& this.x == other.x
&& this.y == other.y;
}
In dieser Art hat das Brian Goetz auch für das JDK committed. Klar, das ist kürzer und einfacher zu lesen. Der Knaller aber ist, dass der Spaß auch noch schneller ist (wobei das auch davon abhängt, womit man vergleicht):
Code:
Benchmark (mode) Mode Cnt Score Error Units
Main.benchmark old thrpt 30 241058,051 ± 4640,652 ops/s
Main.benchmark new thrpt 30 629972,551 ± 11241,051 ops/s
Im JEP zum instanceOf pattern matching wird die equals-Methode gar in dieser Weise implementiert:
Java:
public boolean equals(Object obj) {
return (obj instanceof Typ other)
&& this.x == other.x
&& this.y == other.y;
}
Das gefällt mir! Aber warum wird hier sogar völlig auf die Referenzvergleiche verzichtet? José Paumard hat darauf eine Antwort: predictive branching.
Die CPU macht Vorhersagen, welcher Zweig durchlaufen werden wird und kann so die Pipeline besser füllen. Stellt sich heraus, dass die Vorhersage falsch war (der Referenzvergleich muss ja in jedem Fall ausgeführt werden), muss zurückgesetzt werden - was im Verhältnis massig Zeit kostet. In Summe macht dies den Versuch der Optimierung über den Referenzvergleich oft zunichte.
Zuletzt bearbeitet von einem Moderator: