![]() |
Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
Hi,
Ich hätte mal eine Frage: Wie arbeitet case...of ? Ich würde das gerne wissen, da ich eine solche Funktion möglichst effiziert in meine Programmiersprache ![]() MFG |
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
Statt etlicher IF-Abfragen so
Delphi-Quellcode:
Case ergebnis of
1: Prozedur 1; 2: Prozedur 2; ... end; // Case |
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
ich denke eher er wollte wissen wie Delphi das intern übersetzt
|
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
@Wolfgang: Das war glaub ich nicht seine Frage ;)
@olee Die case-Struktur erzeugt eine Sprungtabelle. Du kannst ja einfach mal testweiseeine Case-Struktur in Delphi schreiben, einen Breakpoint darauf setzen und dir dann den Assembler-Code anschauen. Es gab hier vor einigen Monaten mal einen Thread dazu, wo untersucht wurde, wie das die Tabelle genau angelegt wird und welche Optimierungen dabei vorgenommen werden. Leider finde ich den nicht mehr :wall: |
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
|
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
Zitat:
[edit]Ok, mit vor ein paar Monaten hab ich mich wohl vertan. das wird dann wohl der Zeitpunkt gewesen sein, an dem ich den Thread das erste mal gelesen habe :wink: [/edit] |
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
Ok ich denke ich muss meine Frage etwas genauer Ausdrücken ...
Erstmal muss ich sagen, dass dieser Artikel von Lemmy1 recht interessant war und mir auch geholfen hat. Aber soweit wie die Technik da in Post #2 erklärt wurde, war ich auch schon.... Das Problem das sich mir stellt ist mit diesen Wertebereichen wie z.B.
Delphi-Quellcode:
Bei diesem Beispiel bin ich mir noch nicht so recht sicher, wie ich das lösen kann.
case AChar of
'a'..'z', 'A'..'Z', '_' : begin Tu_Dies; end; '0'..'9', '.' : begin Tu_Das; end; end; Mein bisheriger Ansatz wäre es, diese Teilbedingungen ('a'..'z', 'A'..'Z', '_') aufzuteilen in so 3 "virtuelle" case Abschnitte, wovon 2 jeweils zu dem mit dem eigentlichen Code springen würden. MFG |
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
Zitat:
|
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
Zitat:
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:
Vergleich - keine Tabelle
case value of
1: xxx1; 2..5: xxx2; 6: xxx3; 8: xxx4; else xxx5; end;
Delphi-Quellcode:
Vergleich - keine Tabelle - unoptimales durch alles gespringe, dafür weniger vorausberechnungen nötig, um die Sprungtadressen anzupassen, da jedes CASE nur sich kennen muß.
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: 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:
Verrechnen - keine Tabelle
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:
Delphi-Quellcode:
Vergleich - Tabelle
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:
Delphi-Quellcode:
Verrechnen - Tabelle
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:
Delphi-Quellcode:
Vergleiche auf 0 sind ja einfacher
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: 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 |
Re: Funktionsprinzip von Case...Of (Interne Arbeitsweise??)
Ohje...
Da werde ich einiges zu implementieren haben in RUTIS... Vor allem wird es unangenehm, immer den Code vom Case-Abschnitt und dessen Bedingung gleichzeitig zu erstellen, da ich so den Case-Code unten anfügen muss und dessen Bedingung weiter oben :pale: Naja aber ich denke ich werde es hinbekommen :mrgreen: Danke für die Hilfe! :thumb: MFG |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz