Vergleichende Bytecode-Analyse

vorhergehende Artikel in: Java Rants
04.06.2016

Nachdem ich in einem meiner vorherigen Artikel über Pläne zu meiner Weiterbildung schrieb, habe ich nochmals einen Gedanken wieder aufgegriffen, mit dem ich mir schon verschiedentlich die Zeit vertrieb...

Einleitung

Ich habe mir die Möglichkeit geschaffen, Benchmarks für Arme durchzuführen. Damit habe ich verschiedene syntaktische Konstrukte analysiert, die dem Ergebnis nach äquivalent sind, um herauszubekommen, ob es bei einer davon eventuell einen Laufzeitvorteil gibt.

Ich habe bereits in einem früheren Artikel über meine Ablehnung gegenüber syntactic sugar geschrieben. Ich muss hier gleich vorausschicken, dass das, was ich in diesem Artikel geschrieben habe durch meine Analysen falsifiziert wurde.

Den Quelltext der Klasse, mit der ich die Benchmarks durchführte, ist an unten in diesem Artikel angehängt. Die Bytecodes sieht man, indem man das Kommando

javap -c -private 

auf die kompilierte Klasse anwendet.

Cast gegen implizite Konvertierung

Ich untersuchte die verschiedenen Möglichkeiten, ints zu doubles zu machen bei Berechnungen: In Java würde folgendes Konstrukt

int a=1;
int b=3;
double result=a/b;

zu einem Wert von 0.0 für die Variable result führen, da die Rechte Seite zuerst ausgewertet und dann der Double-Variable zugewiesen wird. Wer als Resultat 0.3333333 sehen möchte, muss dafür sorgen, dass a und b bei der Auswertung der rechten Seite als Double-Zahlen angesehen werden. Das kann man auf vewrschiedenen Wegen erreichen: einmal kann man beide Zahlen vor der Auswertung mit 1.0 multiplizieren - das entstehende Zwischenergebnis ist dann eine Double-Zahl und damit ist der gesamte Ausdruck auf der rechten Seite ebenfalls eine:

double result=(a*1.0)/(b*1.0);

Die zweite Möglichkeit ist ein expliziter Cast:

double result=(double)a/(double)b;

In der Auswertung der Benchmarks unterschieden sich beide Lösungen nicht voneinander - mal war die eine marginal schneller, mal die andere. Ein klarer Fall von Syntactic sugar.

Drei verschiedene Arten über eine Liste zu iterieren

Die zweite Sache, die mich interessierte war die Frage, ob sich bei den unterschiedlichen Arten, über eine Liste zu iterieren Unterschiede ergäben. Ich hatte zunächst nur im Sinn, zu kontrollieren, ob sich Unterschiede in der Ausführungszeit ergeben, wenn man faul ist und

for(int i=0;i<l.size();++i)

statt

int size=l.size();
for(int i=0;i<size;++i)

schreibt. Wenig überraschend ergab sich ein leichter Vorteil für Lösung zwei: Die Funktion wird tatsächlich bei jedem Schleifendurchlauf ausgewertet, was für das etwas schlechtere Laufzeitverhalten sorgt. Nachdem ich damit fertig war, wollte ich wieder eine Bestätigung des "syntactic sugar"-Vorurteils haben und probierte:

for (String string : l)

Ich fiel fast vom Stuhl: Wo meine beiden ersten Versuche um die 6 Sekunden brauchten, brauchte diese Variante unter ansonsten identischen Voraussetzungen um die 10 Millisekunden!! Das ist ein Speedup von fast 1000!!! Jetzt ist es denke ich an der Zeit, meinen Code auf die Benutzung der Funktion size() zu untersuchen und überall da, wo anhand dieser Funktion iteriert wird, Änderungen einzuführen...

Lizenz
ByteCodeAnalysis

Artikel, die hierher verlinken

Seiteneffekt-freie Programmiersprachen

05.04.2021

Ich habe mich hier verschiedentlich darüber ausgelassen, was Syntactic sugar in Java bedeutet und was man beachten sollte, um mit einigen einfachen Mitteln die Performanz von Java-Anwendungen zu steigern.

Java Collections und Slices

20.03.2021

Ich hatte neulich einen Fall, in dem ich nicht nur über die Elemente einer Liste iterieren wollte, sondern über einen Satz von jeweils drei benachbarten Elementen (Element und sein Nachfolger/Vorgänger)

Lambda Expressions vs. anon. Inner Classes

13.01.2019

Angefangen hat alles mit der Information, dass ein Meetup hier in der Nähe zum Thema "Java upside down: funktionale Programmierung in Java mit Vavr"

Alle Artikel rss Wochenübersicht Monatsübersicht Github Repositories Gitlab Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Alte Rechner zukunftsfähig (?)

    01.05.2019

    Ich mache immer wieder gerne Experimente mit Terminalsessions - meistens wegen der zentral möglichen Administration. Nunhabe ich das Thema von neuem angepackt: wegen einem alten(sehr alten) Laptop, der bei mir schon so lange im Schrank lag, dass sogar die BIOS-Batterie inzwischen leer war...

    Weiterlesen...

Neueste Artikel

  • Graphics2D Implementierung für Java mit verlegtem Koordinatenursprung

    Es gibt seit vielen Jahren immer mal wieder Leute, die im Internet fragen, ob man in Javas diversen Methoden zum Zeichnen von Graphiken das Koordinatensystem so ändern könnte, dass sich der Koordinatenursprung links unten befindet und die positive y-Achse nach oben weist. Meist sind die Antworten dann, dass eine Affine Transformation eingeschaltet werden solle, die das Bild spiegelt.

    Weiterlesen...
  • Unerwartete Probleme bei der Software Raid5 Erweiterung

    Ich bin an die Grenzen meiner Storagelösung gestoßen - es musste mehr Platz her...

    Weiterlesen...
  • Die sQLshell ist nun cloudnative!

    Die sQLshell hat eine weitere Integration erfahren - obwohl ich eigentlich selber nicht viel dazu tun musste: Es existiert ein Projekt/Produkt namens steampipe, dessen Slogan ist select * from cloud; - Im Prinzip eine Wrapperschicht um diverse (laut Eigenwerbung mehr als 140) (cloud) data sources.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muß damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.