![]() |
Re: Codedesign
Nested functions haben auch noch weitere Vorteile.
Erstens hat man eine Teilfunktionalitaet isoliert, die man bestimmt bald als lokale Funktion brauchen kann. Ganz anders ist der Vorteil das man Zugriff auf uebergeordnete Variablen hat. Das muss man allerdings sorgfaeltig evaluieren, da es sehr unuebersichtlich werden kann. |
Re: Codedesign
Hallo choose,
wäre vielleicht mal ganz nett, wenn du deinen Beitrag ins Deutsch übersetzen könntest, ich als Hochschulabgänger und Softwareentwickler versteh ihn nämlich nicht! Nimoee |
Re: Codedesign
Hallo Nimoee,
ich bin den Text noch einmal durchgegangen, Du hast Recht: Obwohl ich mir Mühe gegeben habe, sind in der Tat noch einige englische Begriffe im Text vorhanden... Mit den folgenden Begriffen meinte ich das:
Ich hoffe, dass ich Dir damit helfen konnte. Wie ich im letzten Posting schon erwähnte, es sind eher Entwurfsentscheidungen (und ein bisschen Vorgehensmodell), die ich hier aufgezählt habe. Trotzdem beeinflussen einige von ihnen stark die lesbarkeit des Codes. |
Re: Codedesign
Zurück zum Thema, ihr meint also, dass ich die wichtigesten Regeln gefunden habe oder könnte man noch was ergänzen? Es soll eigentlich ein kleiner Artikel für Einsteiger werden. Und so tief wie choose wollte ich nicht in die Materie einsteigen, damit dürften Anfänger überfordert sein.
|
Re: Codedesign
Naja, eines noch: man sollte wissen wie was wann der Compiler compiliert :-)
D.h. man sollte wissen was die einzelnen Aufruf Konventionen für direkte und indirekte Auswirkungen auf das beste Codedesign haben. Zb. arbeiten wir standardmäßig mit Register Aufrufkonvention. Beachtet man im Design das jede Funktion max. 3 Parameter ordinalen Types hat -> Integer/Pointer und Klassen Methoden max. 2 solcher Parameter, dann ist dies die optimale Vorgehensweise damit der Optimierer schnellen Code erzeugen kann. Man sollte dann auch bedenken das die Anzahl der lokalen Variablen in den Proceduren gering gehalten wird. Auch dies ermöglicht dem Optimierer die bestmögliche Arbeitsweise um mit den vorhandenen Registern jonglieren zu können. Auch deshalb sind nested Proceduren sinnvoll. Denn der Optimeirer optimiert jede Funktion für sich gesehen. Je einfacher und linear strukturiert eine Procedure ist je besser kann der Optimierer seine Arbeit machen. Es gibt also direkte Abhänigkeiten des erzeugten Codes durch den Compiler zum gewählten Design. In kurz: - 3 ordinale Paramter maximal für Proceduren - 2 ordinale Paramter maximal für Methoden (Self ist der 3. unsichtbare Parameter) - register Aufrufkonvention wenn möglich - Result immer nur am Ende der Funktion belegen, oder vor einem Exit; - möglichst wenige lokale unkomplizierte Variablen - das Aufsplitten komplexer Funktionen auf mehrere weniger komplexe Funktion macht den Code meistens schneller, da der Optimierer besser arbeiten kann (gilt auch für nested Proceduren) Mit dem Result hier ein Source:
Delphi-Quellcode:
In komplexeren Sources wird nämlich in BadResultUsage das Resultat im Stack zwischen gespeichert. In GoodUsage geben wir aber dem Optimierer in J die Berechnungsvariable vor, die der Optimierer innerhalb der Loop in ein Register optimieren kann. Erst am Ende der Funktion wird das Resultat belegt, was meistens durch den Optimierer einfach bedeutet das er das optimierte Register J ind Register EAX kopiert. In BadResultUsage wäre dies aber im Stack gespeichert.
function BadResultUsage: Integer;
var I: Integer; begin Result := 1; for I := 0 to 1024 do Result := Result + Result; end; function GoodUsage: Integer; var I,J: Integer; begin J := 1; for I := 0 to 1024 do J := J + J; Result := J; end; Wohlgemerkt obige Beispiele sind zu einfach, das heist der Optimierer kann so wie sie sind beide optimal umsetzen. Würde man aber viel mehr Code drinnenstehen haben tritt diese Regel in Kraft. Nochwas: man sollte nach Möglichkeit mit Funktionen mit ordinalen Rückgabewerten arbeiten. Proceduren mit Reückgabeparametern bei Referenzen sind ineffizienter.
Delphi-Quellcode:
Gruß hagen
procedure BadResultProc(var Result: Integer; Data: Integer);
begin Result := Result + Data; end; function GoodResultFunc(PrevResult, Data: Integer): Integer; begin Result := PrevResult + Data; end; |
Re: Codedesign
Gute Tipps, wußte ich auch noch nicht. Aber ich weiß nicht, ob ich das noch einbaue, da der Artikel nicht compilerabhängig sein sollte. Mal sehen eventuell als anhang oder so. hast du dazu noch irgendwelche quellen im Internet oder so?
|
Re: Codedesign
Bei Prozedure/Funktionen/Methoden die mit Interface/Floatingpoints/Variant/Strings Paramter arbeiten sollte man const Paramter benutzen.
const deklarierte Paramter verhindern das der Compiler das nötige Referenzecounting bei diesen komplexen Typen durchführt.
Delphi-Quellcode:
Im zweiten Falle weiß der Compiler durch die const Deklaration das sich nichts and den Daten ändern wird, es geht auch garnicht. Dadurch kann er sich die Einrichtung eines unsichtbaren try finally end Blockes und den Code für's Referenzecounting vollständig sparen.
procedure BadRefCountedTypes(Data: String/Variant/Interface);
begin // _AddRef(Data); // intern durch Compiler erzeugt // try if Data <> ... then ; // finally // _Release(Data) end; procedure GoodRefCountedTypes(const Data: String/Variant/Interface); begin if Data <> ... then ; end; Bei Interfaces zB. sind Parameter die nicht const deklariert wurden fast immer schlecht deklariert, da man sie eigentlich immer nur als const oder var benutzen kann. Gruß Hagen |
Re: Codedesign
Zitat:
Selbst in den Borland NewsGroups existieren darüber falsche Ansichten, auch bei TeamB Mitgliedern. Gruß Hagen PS: man kann sich die logischen Abhänigkeiten aus der Delphi Hilfe ableiten, mit ein wenig Geschick :) |
Re: Codedesign
Hm, gut. Mal sehen, ob ich die gepordnet da unterbringen kann. Jetzt koche ich mir aber ertsmnal meine Eier.
|
Re: Codedesign
Zitat:
Wo genau soll denn der Schwerpunkt Deines Artikels liegen? Deine bisherigen Vorschläge scheinen sich auf Wartbarkeit zu beziehen. Hagen schein die Erweiterbarkeit im Sinn zu haben Zitat:
Was aber willst Du in Deinem Artikel darstellen? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:42 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-2025 by Thomas Breitkreuz