Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.157 Beiträge
 
Delphi 12 Athens
 
#9

Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)

  Alt 15. Feb 2010, 06:05
Zitat:
'a'..'z', 'A'..'Z', '_' :
Hier mußt du ja nur den Vergleichsteil aufteilen.
Selbst a..b kannst du ja nicht auf einemal auswerten und brauchst praktisch mehrere Vergleiche.
Unten hab ich jetzt nur ein a..b drin, aber im Prinzip wird da ja dann einfach nur alles nacheinander verglichen und dann in das eine zugehörige CASE gesprungen.


Es gibt im Prinzip mehrere Möglichkeiten, wie es Delphi und seine Verwandten intern lösen.

Ich schreib es jetzt mal in Pascal, statt ASM, damit's verständlicher/einfacher ist:

- direkte Vergleiche
- oder berechnen und mit 0 vergleichen

- die Vergleiche vor den jeweiligen Blöcken
- oder über eine Sprungtabelle am Anfang, hier kann man den Wert die ganze Zeit in einem Register lassen und geht so die Liste sehr flott durch

Wenn die Werte "weit" mehr als 1 Schritt (wo man SUB statt DEC nutzen muß) liegen, dann kann man auch direkt vergleichen.
Liegen viele Werte nah beieinander, dann macht sich das Berechnen schon besser.

Für dich dürfte die Tabelle am Anfang besser sein,
aber wenn man selber den ASM-Code schreibt und öfters mal was verändert/erweitert/löscht,
dann wäre da die 1. Variante wiederum besser (in diesem Fall weniger fehleranfällig und übersichtlicher)

Das Ausgangsprodukt:
Delphi-Quellcode:
case value of
  1: xxx1;
  2..5: xxx2;
  6: xxx3;
  8: xxx4;
  else xxx5;
end;
Vergleich - keine Tabelle
Delphi-Quellcode:
temp := value; // falls value eine Berechnung oder Degleichen ist
if temp <> 1 then goto j2;
xxx1;
goto yend;
j2:
if temp < 2 then goto j3;
if temp > 5 then goto j3;
xxx2;
goto yend;
i3:
if temp <> 6 then goto j4;
xxx3;
goto yend;
i4:
if temp <> 8 then goto jelse;
xxx4;
goto yend;
jend:
xxx5;
yend:
Vergleich - keine Tabelle - unoptimales durch alles gespringe, dafür weniger vorausberechnungen nötig, um die Sprungtadressen anzupassen, da jedes CASE nur sich kennen muß.
Allerdings bibt es hier kein ELSE, außer man prüft dort so, als wäre es ein normales CASE auf alle Werte der anderen CASE, mit negativem Ergebnis, bzw. man führt eine weitere Temp-Variable "wurde-was-anderes-schon verarbeitet" mit.
Delphi-Quellcode:
temp := value; // falls value eine Berechnung oder Degleichen ist

if temp = 1 then goto j1;
goto j1end;
j1:
xxx1;
j1end:

if temp >= 2 then goto j2;
if temp <= 5 then goto j2;
goto j2end;
j2:
xxx2;
y2end:

if temp = 6 then goto j3;
goto y3end;
i3:
xxx3;
y3end:

if temp = 8 then goto j4;
goto y4end;
j4:
xxx4;
j4end:
Verrechnen - keine Tabelle
Delphi-Quellcode:
temp := value; // nötig, weil mit dem Wert ja gerechnet wird
dec(temp);
if temp <> 0 then goto j2;
xxx1;
goto yend;
j2:
dec(temp);
if temp <> 0 then goto j3;
dec(temp, 3);
if temp > 0 then goto j3;
xxx2;
goto yend;
i3:
dec(temp);
if temp <> 0 then goto j4;
xxx3;
goto yend;
i4:
dec(temp, 2);
if temp > 0 then goto jelse;
xxx4;
goto yend;
jend:
xxx5;
yend:
Vergleich - Tabelle
Delphi-Quellcode:
temp := value; // falls value eine Berechnung oder Degleichen ist
if temp = 1 then goto j1;
if (temp >= 2) and (temp <= 5) then goto j2;
if temp = 6 then goto j3;
if temp = 8 then goto j4;
//jelse:
xxx5;
goto yend;
j1:
xxx1;
goto yend;
j2:
xxx2;
goto yend;
i3:
xxx3;
goto yend;
i4:
xxx4;
yend:
Verrechnen - Tabelle
Delphi-Quellcode:
temp := value; // nötig, weil mit dem Wert ja gerechnet wird
dec(temp);
if temp = 0 then goto j1;
dec(temp, 4);
if temp < 0 then goto j2;
dec(temp);
if temp = 0 then goto j3;
dec(temp, 2);
if temp = 0 then goto j4;
//jelse:
xxx5;
goto yend;
j1:
xxx1;
goto yend;
j2:
xxx2;
goto yend;
i3:
xxx3;
goto yend;
i4:
xxx4;
yend:
Vergleiche auf 0 sind ja einfacher
und wenn man mit dem Wert rechnet, dann kann man das Berechnungsergebmis auch gleich noch mit ausnutzen und so den Vergleich sparen:
Delphi-Quellcode:
dec(temp);
if temp <> 0 then goto j3;
Code:
dec &temp
jnz @@j3
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat