Entwickler-Ecke

Algorithmen, Optimierung und Assembler - if-Abfrage Performance


Heiko - So 27.03.05 14:55
Titel: if-Abfrage Performance
Die Frage die ich jetzt stelle ist heutzutage zwar kaum noch von Bedeutung, hoffe aber trotzdem das jemand mir darauf antworten kann.
Mich würde mal interessieren welche der beiden folgenden Quelltexte eine bessere Performance hat.


Delphi-Quelltext
1:
2:
3:
4:
if Form1.CheckBox1.Checked and Form1.Edit1.Text='blabla' then
 begin
  ...
 end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
if Form1.CheckBox1.Checked then
 begin
  if Form1.Edit1.Text='blabla' then
   begin
    ...
   end
 end



Moderiert von user profile iconTino: Topic aus CLX / Delphi Language (Object-Pascal) verschoben am Do 28.04.2005 um 10:16


Harry M. - So 27.03.05 15:03

ich habe zwar keine ahnung was du für einen rechner hast oder warum das für dich von bedeutung ist, aber ich den das mit den weingsten code sollte am schnellsten durchlaufen sein


delfiphan - So 27.03.05 15:10

Die Frage ist berechtigt, da bei der 2. Methode das zweite If nicht mehr ausgewertet wird, wenn das erste If false ergab. Man könnte meinen, dass man deswegen im Schnitt Zeit spart. Aber auch im zusammengesetzten Fall wird die Auswertung der If-Ausdrücke abgebrochen, sobald das Resultat (vorzeitig) bekannt ist. Das ist eine Compileroptimierung.

Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
Var I: Integer;
begin
 I := 0;
 if (I <> 0and (1/I = 1then
 // ...

Das ergibt keine Division durch Null, da der zweite Term gar nicht erst ausgewertet wird. Diese Optimierung kann man mit der Compilerswitch {$B+} ausschalten.


Heiko - So 27.03.05 15:18

thx delfiphan,

Ich kenne leider die Compilereigenschaften nicht, wehalb ich gefragt habe. Den Gedanken, von dir, im ersten Absatz hatte ich auch, dachte mir aber, dass das ungefähr Ausgeglichen wird. Hatte mir aber Gedacht ich frage lieber nach. Kann es aber sein, dass Delphi vielleicht den 2. Quelltext in sich ausführt ohne dass der Entwickler davon etwas mitbekommt?

@User-Xy2004: Dass das mit dem kürzeren Quelltext schneller ist, als das mit dem längere Quelltext, stimmt nicht immer, wehalb ich mich nicht darauf geschlußfolgert habe.


uall@ogc - So 27.03.05 15:32

1) beides wird in die selben asembler anweisungen umgesetzt, demnach ist beides gleich schnell
2) ist das erste voll quelltext her besser aufgebaut
3) wird das erste bei dir nicht funktionieren da du mal wieder keine klammern gesetzt hast was man IMMER machen und sich mal direkt angewöhnen sollte


delfiphan - So 27.03.05 15:44

@uall: Ich hab den Assemblercode nicht angeschaut, hab aber einige Milliarden Durchgänge berechnen lassen und schon einen gewissen Zeitunterschied zwischen den beiden Methoden festgestellt. Könnte aber ein Cache Effekt sein, oder sonst was. Hab es nicht länger untersucht.


uall@ogc - So 27.03.05 15:46

hab debuggt und 2 mal den selben code vorgefunden, die "and"s werden vom comiler eh in ifs umgewandelt ;P


Heiko - So 27.03.05 16:51

@uall@ogc: Das die Klammern fehlen ist mir gar nicht aufgefallen. Bei diesem Fehler würde Delphi, beim Compilieren, sowieso eine Fehlermeldung zurückgeben und da ich aber mir den Quelltext für diesen Thread nur ausgedacht habe und ihn nicht in Delphi umgesetzt habe, hatte ich in diesem Moment nicht daran gedacht.


uall@ogc - So 27.03.05 16:54

es kann aber auch sein das kein fehler auftritt... aber die abfrage dann was ganz anderes macht


Heiko - Mo 28.03.05 11:12

Was macht der Compiler eigentlich bei einer Or-Verknüpfung?


uall@ogc - Mo 28.03.05 14:17

genau as selbe nur die jumps wischen den if abfragen (cmps) sind anders, d.h.
wenn die erste anweisung schon wahr ist wird schon in den code gespurngen, dumm ist aber das sowas in delphi nicht möglich ist in c++ aber schon:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function blub: boolean;
begin
  result := true;
  messagebox(0,'asdasd',nil,0);
end;


if (true) or (blub) then
//


die messagebox wird nie aufgerufen obwohl es manchmal schon einen sinn hat (z.b. bei blub würde etwas in eine liste eingetragen werden, egal ob das bei if gemacht werden muss oder nicht.

c++ bzw java kennt da den unterschied zwischne | und ||
ausserdem machen sie auch noch nen unterschied bei & und &&

z.b. wäre sowas nicht in delphi möglich:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function blub: boolean;
begin
  result := true;
  messagebox(0,'asdasd',nil,0);
end;


if (false) and (blub) then
//


die messagebox wird hier uahc net aufgerufen

aber das nur so am rande


SvenAbeln - Mo 28.03.05 14:45

Aber sicher ist dies auch in Delphi möglich.

Zitat:

z.b. wäre sowas nicht in delphi möglich:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function blub: boolean;
begin
  result := true;
  messagebox(0,'asdasd',nil,0);
end;


if (false) and (blub) then
//



die messagebox wird hier uahc net aufgerufen



Schau dir mal die Compiler Optionen an.

Zitat:

Die Direktive $B schaltet zwischen zwei unterschiedlichen Modellen der Code-Generierung für die Booleschen Operatoren and und or um.
Im Status {$B+} erzeugt der Compiler Code für die vollständige Auswertung eines Booleschen Ausdrucks. Das bedeutet, dass jeder Operand eines Booleschen Ausdrucks, der mit den Operatoren and und or gebildet wird, garantiert ausgewertet wird, auch wenn das Ergebnis des gesamtes Ausdrucks bereits feststeht.

Im Status {$B-} generiert der Compiler Code für die Kurzschlussauswertung Boolescher Ausdrücke, d. h. die Auswertung wird beendet, sobald das Ergebnis des gesamten Ausdrucks feststeht (die Auswertung erfolgt immer von links nach rechts).


Oder für das ganze Projekt unter den Projekt-Optionen, da heißt es dann:
Boolesche Ausdrücke vollständig


uall@ogc - Mo 28.03.05 14:48

ok möglich ist es aber halt nur mit compiler schaltungen die die wenigsten auswendig kennen ;> nen andf oder so oder nen @and and^ and_ bzw wäre schön zu haben


Heiko - Do 29.12.05 10:32

user profile iconuall@ogc hat folgendes geschrieben:
ok möglich ist es aber halt nur mit compiler schaltungen die die wenigsten auswendig kennen ;> nen andf oder so oder nen @and and^ and_ bzw wäre schön zu haben


Würde ich ein bissl sinnlos finden. Die aktuelle Lösung von Borland für Delphi halte ich schon für ganz in Ordnung, da man doch meistens nur eine Variante verwendet (die kurze) ;).


alzaimar - Mo 02.01.06 21:44

user profile iconuall@ogc hat folgendes geschrieben:
ok möglich ist es aber halt nur mit compiler schaltungen die die wenigsten auswendig kennen ...

Was? Entweder man verwendet eine Sprache, die wohldefiniert ist, oder einen Makroassembler wie C(++). Nebenbei sind die Compileroptionen für jeden ernsthaften Programmierer sehr wichtig, weswegen man sie tunlichst kennen sollte: Man entwickelt i.a. mit Overflowchecks und Rangechecks, Assertions sowie Debuggersymbolen. Wenn die Anwendung denn dann mal stabil läuft, schaltet man den Schmoo ab. Die vollständige Berechnung boolscher Ausdrücke ist Pascal-Standard, die Optimierung eine Delphi-Eigenheit (ja ja, eigentlich von allen Compilern).
Compilerswitches im Sourcecode vermeide ich. Aber nur deshalb, weil ich mir die blöden Kürzel sowieso nicht merken kann...