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 Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    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, muss 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 Codeberg-Repositories findet man hier.