Kettenanweisung oder Einzelschritte

xX_QueAnw_Xx

Mitglied
Hey hab 1ne Frage zum Thema GEschwindigkeit bzw. COde Strukturierung:
Ist es sinnvoll solche Kettenanweißungen wie die Follgende zu schreiben, oder lieber alles in kleinen unterschritten?

Java:
try {
[code]jLabel1.setFont(
     Font.createFont(Font.TRUETYPE_FONT,
            new File(getClass().getResource("/Fonts/Hitman.ttf").toFile())).deriveFont(Font.PLAIN, 23));
        } catch (FontFormatException ex) {
            Logger.getLogger(Register.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Register.class.getName()).log(Level.SEVERE, null, ex);
        }
 
Zuletzt bearbeitet von einem Moderator:
F

Firephoenix

Gast
Hi,
zuallererst würde ich Lesbarkeit voranstellen, dannach Performance.
Ob man damit wirklich was gewinnt halte ich eher für fragwürdig ;)
Gruß
 

musiKk

Top Contributor
Kann man wie so oft nicht pauschal sagen. Zwei positive Eigenschaften von mehr Variablen sind jedoch:

1. Variablennamen sind Dokumentation. Wenn sie sinnvoll gewählt sind, kann das zum Verständnis des Codes beitragen.
2. Des weiteren steht in einem Stacktrace als kleinstes Element eine Zeilennummer. Wenn in einer tief verschachtelten Zeile z. B. eine NPE auftritt, ist einem nicht viel geholfen.

Übertreiben sollte man es natürlich auch nicht. Wie Firephoenix schon sagt: Lesbarkeit ist das A und O.
 

xX_QueAnw_Xx

Mitglied
Ok,aber Lesbarkeit erreiche ich auch durch kommentieren was ich regelmäßig tuhe.

Also Performance Technisch macht es wenig Unterschied? Auch wenn ich deklarationen dieser art (Für Fonts) c.a. 30 Stück habe?

Ich werde diese Schnippsel jetzt eh in einer anderen Klasse umsetzten dann habe ich eine widerverwendbarkeit für externe schrift erreicht.

:)
 

Marco13

Top Contributor
Du machst sowas doch nicht wirklich für 30 Labels :autsch: ?!

Ich bin jemand, der grundsätzlich solche Sachen wie
Code:
Object value = someObjectWithLongName.getSomeSpecificThing().andYetAnotherGetter().nowThisIsReallyBecomingDeeplyNested().doYouStillKnowWhereWeStarted().probablyNot();
eher als
Code:
SpecificThing t = someObjectWithLongName.getSomeSpecificThing();
Getter g = t.andYetAnotherGetter();
Nested n = g.nowThisIsReallyBecomingDeeplyNested();
Started s = n.doYouStillKnowWhereWeStarted();
Object value = s.probablyNot();
schreibt. Wie "konsequent" man das umsetzt bleibt eigentlich jedem überlassen, aber das Beispiel mit den NullPointerExceptions wurde schon genannt, und wenn in so einem Schnipsel sogar checked Excetpions fliegen wird's noch offensichtlicher.

Und weil es um Geschwindigkeit ging: Vergiß es :noe: Wenn du ein TTF lädst, dann knarzt die Festplatte mal kurz, und in der Zeit, die er braucht, um die Daten von der Platte zu laden, hätte er Hunderttausende von Labels erstellen können - DAS ist das, was dort Zeit braucht (und in der Zeit, die die Schallwellen brauchen, um von der Festplatte zu deinem Ohr zu gelangen, hat er sich's schon wieder gemütlich gemacht und wartet auf deine Eingaben... ;) )
 

Ark

Top Contributor
Code:
SpecificThing t = someObjectWithLongName.getSomeSpecificThing();
Getter g = t.andYetAnotherGetter();
Nested n = g.nowThisIsReallyBecomingDeeplyNested();
Started s = n.doYouStillKnowWhereWeStarted();
Object value = s.probablyNot();
Es ist generell keine so gute Idee, sich von solchen Ketten abhängig zu machen, unabhängig davon, ob dabei eigene Variablen benutzt werden oder nicht. Eine Kette ist nun einmal nur so stark wie ihr schwächstes Glied, und wenn sich da (im Code) einmal an einer Stelle etwas ändert, funktioniert eben die ganze Kette nicht mehr: Klick.

Ark
 

Marco13

Top Contributor
Das war ein Beispiel - genaugenomment kopiert aus einem meiner früheren Beiträge, wo es eigentlich um die 80-Zeichen-Beschränkung für Zeilen ging. Natürlich sollte sowas nicht in "richtigem" Code vorkommen, aber schon bei "zwei Stufen" finde ich es günstiger, sich erst das Objekt zu holen, und dann darauf zu arbeiten - auch wieder NUR ein Beispiel:
Code:
someThing.getSomeObject().setup();
someThing.getSomeObject().prepare();
someThing.getSomeObject().execute();
someThing.getSomeObject().cleanup();
someThing.getSomeObject().shutdown();
IMHO besser:
Code:
SomeObject someObject = someThing.getSomeObject();
someObject.setup();
someObject.prepare();
someObject.execute();
someObject.cleanup();
someObject.shutdown();
 
D

Dow Jones

Gast
Ist es sinnvoll solche Kettenanweißungen wie die Follgende zu schreiben, oder lieber alles in kleinen unterschritten?

Es gibt sogar noch mehr Möglilchkeiten wie man das formulieren kann. Welche davon sinnvoll ist darfst du - wie die anderen schon alle schrieben - selber für den Einzelfall entscheiden. :)

Performance:
Ich habe das gerade mal ausprobiert, und das Ergebnis ist wie erwartet. In beiden Fällen werden bei jedem einzelnen Funktionsaufruf temporäre Objekte erzeugt. Der Unterschied ist jediglich, das im "Einzelschrittmodus" die Referenzen auf diese Objekte noch explizit weggespeichert werden, während sie im "Multistepmodus" nur temporär gespeichert sind.

Java:
		String test = "test";
		test = test.toLowerCase();
		test = test.toUpperCase();
wird in folgenden Bytecode übersetzt (Ausschnitt):
Code:
   3:	aload_1
   4:	invokevirtual	#3; //Method java/lang/String.toLowerCase:()Ljava/lang/String;
   7:	astore_1
   8:	aload_1
   9:	invokevirtual	#4; //Method java/lang/String.toUpperCase:()Ljava/lang/String;
   12:	astore_1
In den Zeilen 7 (und 8) ist zu erkennen das die Referenz auf den LowerCaseString gespeichert wird. Der andere Fall, mit der Kettenanweisung, schaut dagegen so aus:
Java:
		String test = "test";
		test = test.toLowerCase().toUpperCase();
Wird zu folgendem Bytecode übersetzt (Ausschnitt):
Code:
   3:	aload_1
   4:	invokevirtual	#3; //Method java/lang/String.toLowerCase:()Ljava/lang/String;
   7:	invokevirtual	#4; //Method java/lang/String.toUpperCase:()Ljava/lang/String;
   10:	astore_1
Ergo: Ja, die Kettenanweisung ist schneller, da die VM weniger Befehle anzuarbeiten hat. Desweiteren können aus dem nicht-speichern der Referenz weitere Geschwindigkeitsvorteile resultieren, beispielsweise bei der GarbageCollection oder bei der Rate der Cachemisses. Allerdings ist der Geschwindigkeitsgewinn dermaßen gering, das sich solche Lowleveloptimierungen wohl nur dann anbieten wenn die Anweisungen in einem zeitkritischen Bereich millionenfach aufgerufen werden (z.B. beim Rendern eines Frames), oder wenn das Programm auf sehr limitierten Ressourcen laufen soll (z.B. auf einem Handy).

Lesbarkeit
Eigentlich darfst du selber entscheiden wie du das ganze formulierst. Allerdings sollte man schon die Programmierkonvention "the code is not yours" im Hinterkopf behalten. Schreib das Programm so, das nicht nur du sondern auch andere Leute es lesen können. Das macht glaube ich am meisten Sinn.

Demeters Gesetz
Wenn du ganz vornehm sein möchtest kannst du dich auch an das Gesetz von Demeter halten, nach dem Kettenaufrufe gar nicht auftreten dürfen. Hat sicherlich seine Vorteile, aber in deinem Beispiel (deriveFont usw.) würde es wahrscheinlich kein Mensch anwenden... ;)
 

musiKk

Top Contributor
Allerdings ist der Geschwindigkeitsgewinn dermaßen gering, das sich solche Lowleveloptimierungen wohl nur dann anbieten wenn die Anweisungen in einem zeitkritischen Bereich millionenfach aufgerufen werden (z.B. beim Rendern eines Frames), oder wenn das Programm auf sehr limitierten Ressourcen laufen soll (z.B. auf einem Handy).

Und selbst das wird höchstwahrscheinlich durch die VM (v. a. den JIT) optimiert. Zumindest auf Desktops/Servern; ob mobile VMs das leisten weiß ich nicht.
 

Neue Themen


Oben