If-Statement beschleunigen 2 b
Im ersten Teil dieses Posts haben wir uns eine Umgebung gebaut in der wir
- messen können, ob unser Code schneller läuft und
- ob der Code nach der Optimierung immer noch das gleiche tut.
Wir haben also unser Labor aufgebaut und nun können wir mit der Arbeit beginnen.
Hier noch mal der originale Code:
- if(
- (! (diodeMidLeft & 1) && ( !climbing || !ladderMidRight && climbing ) )
- ||
- (! (diodeTopLeft & 1) && ( !climbing || !ladderTopLeft && climbing ) )
- )
- return true;
- else
- return false;
- }
Oder-Verknüpfung aufgelöst:
- if(! (diodeMidLeft & 1) && ( !climbing || !ladderMidRight && climbing ) )
- return true;
- if(! (diodeTopLeft & 1) && ( !climbing || !ladderTopLeft && climbing ) )
- return true;
- return false;
Als zweiten Schritt können wir auch die UND-Verknüpfung auflösen:
- if(! (diodeMidLeft & 1) )
- if( !climbing || !ladderMidRight && climbing )
- return true;
- if(! (diodeTopLeft & 1) )
- if( !climbing || !ladderTopLeft && climbing )
- return true;
- return false;
Nun haben wir wieder eine Oder-Verknüpfung:
- if(! (diodeMidLeft & 1) ){
- if( !climbing )
- return true;
- if( !ladderMidRight && climbing )
- return true;
- }
- if(! (diodeTopLeft & 1) ){
- if( !climbing)
- return true;
- if( !ladderTopLeft && climbing )
- return true;
- }
- return false;
Und schließlich noch mal eine Und-Verknüpfung:
- if(! (diodeMidLeft & 1) ){
- if( !climbing )
- return true;
- if( !ladderMidRight)
- if( climbing )
- return true;
- }
- if(! (diodeTopLeft & 1) ){
- if( !climbing)
- return true;
- if( !ladderTopLeft)
- if( climbing )
- return true;
- }
- return false;
Das war's.
Wie und wann kann man Auflösen?
ODER
- if(A || B || C)
- foo();
- // ist das selbe wie
- if(A)
- foo();
- else if(B)
- foo();
- else if(C)
- foo;
"Else if" ist hier notwendig um eine mehrfache Ausführung von foo zu verhindern. Würde statt foo die Funktion mit return verlassen werden, könnte man einfache If-Anweisungen unter einander schreiben, da der Code nach return ohnedies nicht mehr ausgeführt werden würde
- if(A || B || C)
- return true;
- // ist das selbe wie
- if(A)
- return true;
- if(B)
- return true;
- if(C)
- return true;
UND
- if(A && B && C)
- foo();
- // ist das selbe wie
- if(A)
- if(B)
- if(C)
- foo();
Problematisch sind If-Anweisungen, die eine Else-Klause besitzen und die "nur" Code ausführen ohne den Code mit return verlassen. Hier sind nur sehr selten Auflösungen möglich.
Fazit:
Ich habe hier grundlegend die Möglichkeit der Optimierug ausgezeigt. Wir haben jedoch auch gesehen, dass der, dazu nötige, Aufwand nicht zu unterschätzen ist und die Beschleunigung unter Umständen nicht sehr groß ist. Bei mir lief der optimierte Code um 7 Millisekunden schneller (Bitte nicht übersehen, dass er 1.000.000 mal ausgeführt wird). Deshalb sollte man sich genau überlegen ob und an welchen Funktionen im eigenen Code man Hand anlegen sollte. Natürlich kommen die Funktionen, die am häufigsten ausgeführt werden am ehesten in Frage.
Ich habe im ersten Teil erwähnt, dass ich den Beispielcode gekürzt habe, da wir sonst über 2.000 Prüfungsfälle gehabt hätten. Ein Array mit 2000 Prüfungsfällen schreibt man natürlich nich von Hand. Hier schreibt man sich ein kurzes Programm, das das gewünschte Array ausgibt. Wenn man dieses Programm nicht schreiben kann oder will, kann man auch einen "brute-force" Angriff auf die Funktion starten. Hierbei erzeugt man die einzelnen Parameter zufällig und lässt den Test so lange laufen, bis wahrscheinlich alle Testfälle ausgeführt wurden. Ich halte die zweite Möglichkeit für eher unprofessionell und rate davon ab!
- 0 Comments



Your comment