Version 2003 (Geändert)
Es gibt kein Patentrezept für eine gute Programmiermethode, wir können jedoch die Vorteile gut strukturierter Programme verdeutlichen. Eine gut strukturierte Datenbank erzielt beim Kompilieren viel bessere Ergebnisse als eine wenig durchdachte Datenbank. Schreiben Sie z.B. zum Verwalten von n Objektmethoden eine generische Methode, erhalten Sie sowohl im interpretierten als im kompilierten Modus ein besseres Ergebnis, als wenn n Objektmethoden n-Mal dieselbe Anweisung ausführen.
Mit anderen Worten, die Qualität der Programmierung wirkt sich auf die Qualität des kompilierten Code aus.
Mit der Zeit können Sie Ihren 4D Code schrittweise verbessern. Je häufiger Sie den Compiler einsetzen, desto mehr Fehler können Sie korrigieren und so instinktiv zur effizientesten Lösung gelangen.
Im folgenden geben wir Ratschläge und nennen einige Tricks, die helfen, Zeit beim Ausführen einfacher wiederkehrender Tasks einzusparen.
Code ausführlich kommentieren
Bestimmte Programmiertechniken machen Ihren Code für Sie selbst und später für jemand anderen schwerer lesbar. Deshalb empfehlen wir, Ihre Methoden mit ausführlichen Kommentaren zu versehen. Umfangreiche Kommentare können interpretierte Datenbanken tendentiell verlangsamen, sie beeinträchtigen jedoch nicht die Ausführungszeit in einer kompilierten Datenbank.
Code über Compiler Direktiven optimieren
Über Compiler Direktiven können Sie Ihren Code beträchtlich beschleunigen. Typisieren Sie Variablen nicht gemäss ihrer Verwendung, wählt der Compiler den Datentyp mit der größtmöglichen Reichweite, um die Fehlerquote zu verringern. Typisieren Sie zum Beispiel nicht die Variable in der Anweisung: Var:= 5, verwendet der Compiler als Typ Zahl, auch wenn die Typisierung als Ganzzahl möglich wäre.
Numerische Variablen
Der Compiler gibt numerischen Variablen, die nicht über Compiler Direktiven kompiliert wurden, standardmäßig den Typ Zahl, wenn in den Voreinstellungen nichts anderes festgelegt wurde. Berechnungen auf eine Zahl laufen jedoch langsamer als auf eine Lange Ganzzahl. Wenn Sie wissen, dass eine numerische Variable immer eine Ganzzahl ist, sollten Sie diese über die Compiler Direktiven C_INTEGER oder C_LONGINT deklarieren.
Eine gute Vorgehensweise ist zum Beispiel, Zähler in Schleifen als Ganzzahl zu deklarieren.
Einige Funktionen in 4D geben Ganzzahlen zurück (z.B., Ascii, Int...). Weisen Sie das jeweilige Ergebnis einer nicht typisierten Variablen zu, typisiert der Compiler diese als Zahl und nicht als Ganzzahl. Achten Sie darauf, dass solche Variablen immer mit Compiler Direktiven deklariert werden, wenn Sie sicher sind, dass sie nur in einem Kontext verwendet werden.
Hier ein einfaches Beispiel für eine Funktion, die einen Random Wert mit einer bestimmten Reichweite zurückgibt:
$0:=Mod(Random;($2-$1+1))+$1
Das Ergebnis ist immer eine Ganzzahl. Bei der obigen Anweisung typisiert der Compiler $0 als Zahl und nicht als Ganzzahl oder Lange Ganzzahl. Von daher ist es besser, in die Methode eine Compiler Direktive aufzunehmen:
C_LONGINT($0) $0:=Mod(Random;($2-$1+1))+$1
Dann wird der Parameter rascher zurückgegeben und benötigt weniger Speicherplatz.
Im folgenden Beispiel wurden zwei Variablen als Lange Ganzzahl deklariert:
C_LONGINT($var1;$var2)
eine dritte nicht typisierte Variable erhält die Summe aus den beiden ersten Variablen:
$var3:=$var1+$var2.
Der Compiler typisiert die dritte Variable $var3 als Zahl. Sie müssen sie ausdrücklich als Lange Ganzzahl deklarieren, damit das Ergebnis vom Typ Lange Ganzzahl ist.
Hinweis: Beachten Sie, wie 4th Dimension Ausdrücke berechnet. Erst erfolgt die Berechnung un dann wird das Ergebnis in der Zielvariablen zugewiesen. Im kompilierten Modus bestimmt nicht der Datentyp der Zielvariablen das berechnete Ergebnis, sondern die Datentypen der Operanden.
Im folgenden Beispiel beruht die Berechnung auf Langen Ganzzahlen:
C_REAL($var3) C_LONGINT($var1;$var2) $var1:=2147483647 $var2:=1 $var3:=$var1+$var2
$var3 ist gleich 2147483648 im kompilierten und im interpretierten Modus. Das Minuszeichen beruht auf dem Überlauf, da der Bereich für Lange Ganzzahlen bei 2147483647 endet.
In diesem Beispiel:
C_REAL($var3) C_LONGINT($var1) $var1:=2147483647 $var3:=$var1+1
betrachtet der Compiler den Wert 1 als Ganzzahl. Im kompilierten Modus ist $var3 gleich 2147483648, da die Berechnung auf Langen Ganzzahlen basiert. Im interpretierten Modus ist $var3 gleich 2147483648, da die Berechnung auf dem Typ Zahl beruht.
Schaltflächen sind spezifische Fälle für Zahl, die als Lange Ganzzahl deklariert werden können.
Strings
Alphanumerische Variablen sind standardmäßig vom Typ Text, wenn in den Voreinstellungen nichts anderes definiert wurde. Schreiben Sie zum Beispiel:
MyString:="Hello", typisiert der Compiler MyString als Variable vom Typ Text.
Wird diese Variable häufig durchlaufen, ist es sinnvoll, sie mit der Compiler Direktive C_STRING zu deklarieren. Die Durchführung mit Variablen vom Typ String ist viel schneller, da sie eine max. Länge haben. Beachten Sie die Regeln, die das Verhalten dieser Direktiven bestimmt.
Wollen Sie den Wert eines Zeichens prüfen, vergleichen Sie ihn mit seinem Ascii Wert und nicht mit dem Zeichen selbst. Der reguläre Zeichenvergleich berücksichtigt nämlich alle Möglichkeiten, d.h. auch diakritische Zeichen, wie Akzente.
Besonderheiten bei Arrays, Zeigern, Variablen
Zweidimensionale Arrays
Die Abarbeitung zweidimensionaler Arrays läuft besser, wenn die zweite Dimension größer als die erste ist.
Beispiel: Das Array mit der Deklaration:
ARRAY INTEGER(Array;5;1000)
läuft besser ab, als das Array mit der Deklaration:
ARRAY INTEGER(Array;1000;5)
Felder
Müssen Sie für ein Feld mehrere Berechnungen ausführen, können Sie die Performance verbessern, wenn Sie den Wert dieses Feldes in einer Variablen speichern und die Berechnungen mit der Variablen und nicht mit dem Feld ausführen. Nehmen wir folgende Methode:
Case of : ([Client]Dest="New York City") Transport:="Messenger" : ([Client]Dest="Puerto Rico") Transport:="Air mail" : ([Client]Dest="Overseas") Transport:="Express mail service" Else Transport:="Regular mail service" End case
Diese Methode läuft schneller, wenn Sie schreiben:
$Dest:=[Client]Dest Case of : ($Dest="New York City") Transport:="Messenger" : ($Dest="Puerto Rico") Transport:="Air mail" : ($Dest="Overseas") Transport:="Express mail service" Else Transport:="Regular mail service" End case
Zeiger
Analog zu Feldern laufen Operationen schneller, wenn Sie mit Variablen anstatt mit dereferenzierten Zeigern arbeiten. Müssen Sie mehrere Berechnungen auf eine Variable ausführen auf die sich ein Zeiger bezieht, sparen Sie Zeit, wenn Sie den dereferenzierten Zeiger in einer Variablen speichern.
Nehmen wir zum Beispiel den Zeiger MyPtr, der auf ein Feld oder eine Variable verweist. Sie wollen auf den Wert, auf den MyPtr verweist, verschiedene Tests durchführen. Sie können schreiben:
Case of : (MyPtr-> = 1) Sequenz 1 : (MyPtr-> = 2) Sequenz 2 End case
Die Tests laufen schneller ab, wenn Sie schreiben:
Temp:=MyPtr-> Case of : (Temp = 1) Sequenz 1 : (Temp = 2) Sequenz 2 End case
Lokale Variablen
Verwenden Sie beim Aufbau Ihres Code möglichst häufig lokale Variablen. Die Vorteile liegen auf der Hand:
Lokale Variablen benötigen weniger Speicherplatz beim Einsatz in einer Datenbank. Sie werden beim Aufrufen der Methode erstellt und wieder zerstört, wenn die Ausführung der Methode beendet ist.
Der generierte Code ist für lokale Variablen optimiert, insbesondere beim Typ Lange Ganzzahl. Das ist hilfreich für Zähler in Schleifen.
Referenz
Compiler Direktiven, Einzelheiten zur Syntax, Fehlermeldungen, Richtlinien zur Typisierung.