Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Tricks um Programm zu beschleunigen (https://www.delphipraxis.net/59187-tricks-um-programm-zu-beschleunigen.html)

XeRo 19. Dez 2005 07:46


Tricks um Programm zu beschleunigen
 
Jetzt mal ne allgemeine Frage...ich hab ein Programm (eigentlich trifft es bei vielen programmen zu) das esxtrem langsam ist.

Meine Frage: welche Tricks verwendet ihr um eure programme schneller zu machen?

Pseudemys Nelsoni 19. Dez 2005 07:49

Re: Tricks um Programm zu beschleunigen
 
Neuer PC

Jelly 19. Dez 2005 07:49

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von XeRo
welche Tricks verwendet ihr um eure programme schneller zu machen?

Wir sind alle besser wie :mrgreen:

Nee, im Ernst. Wie sollen wir denn diese Frage pauschal beantworten? :gruebel:

jim_raynor 19. Dez 2005 07:49

Re: Tricks um Programm zu beschleunigen
 
1. Algorhytmus (ist bestimmt wieder falsch geschrieben) optimieren.
2. Umsetzung optimieren.

Optimieren ist ein Vorgang, der sehr von der Aufgabe abhängig ist und ohne zu wissen, was bei dir so langsam ist, kann man dir kaum helfen.

XeRo 19. Dez 2005 07:53

Re: Tricks um Programm zu beschleunigen
 
naja ich suche nach allgemein gültigen aussagen nachdenen man sich richten kann wenn man versucht seine programm schneller zu machen...

z.b.: ist ein unterschied bei den verschiedenen schleifen? (if, while, repeat)???
solche sachen...keine ahnung welche tipps da geben kann...

[eidt]ob man bestimmte units eher vermeiden sollte usw....[/edit]

Pseudemys Nelsoni 19. Dez 2005 07:56

Re: Tricks um Programm zu beschleunigen
 
afaik ist eine forschleife schneller als die anderen beiden, da sie die Bedingung nur einmal prüft.

btw: Algorithmus ;P

Bernhard Geyer 19. Dez 2005 07:58

Re: Tricks um Programm zu beschleunigen
 
Allgemeine Tipps wären:

- Verwende bei Records/Strings/WideStrings const-Parameter.
- Wenn das Programm viel mit Speicheranforderungen/freigabe macht bau einen besseren Speichermanager ein (z.B. FastMM)

Aber ich würde erstmal z.B. mit AQTime schauen wo genau die Geschwindigkeit "verloren" wird. Ich hatte schon genügend Fälle in denen eine zu häufige Aktualisierung der Anzeige (Statusmeldung) die Performancebremse war.

Daniel 19. Dez 2005 08:02

Re: Tricks um Programm zu beschleunigen
 
Die Performance-Optimierung ist eine recht trockene Angelegenheit. Zuerst musst Du in Deiner Anwendung die Stellen finden, die die meiste Zeit benötigen. Nur dort und nirgendwo anders lohnt sich das Optimieren. Ein Werkzeug für so eine Analyse wird zum Beispiel ein Profiler sein.

Und danach geht's entweder um Algorithmik (spannend, aber auch trocken) oder aber um Speichermanagement bzw. Steuerung des Programmablaufes (zum Beispiel über die Direktive "inline").

Pauschal lässt sich diese Frage nicht beantworten - sollte es Dir doch gelingen, hier eine wirklich gute und allgemeingültige Antwort zu finden, so lasse Dir das Verfahren vor Veröffentlichung schützen. ;-)

Je nach Typ Deiner Anwendung könnte ein schnellerer Speichermanager wie FastMM ein wenig helfen, doch die eigentlichen Sprünge wirst Du nur machen könnenm, wenn Du das Problem isolierst und an der Wurzel anpackst.

XeRo 19. Dez 2005 08:08

Re: Tricks um Programm zu beschleunigen
 
ich geb mal mein konkretes beispiel:

unit stammt von Florian Bernd
Delphi-Quellcode:
unit ActiveConnections;

interface

uses windows, classes, Unit1;

procedure ScanNetworkResources(ResourceType, DisplayType: DWord; List: TStrings);

implementation

type
  PNetResourceArray = ^TNetResourceArray;
  TNetResourceArray = array[0..100] of TNetResource;



function CreateNetResourceList(ResourceType: DWord;
                              NetResource: PNetResource;
                              out Entries: DWord;
                              out List: PNetResourceArray): Boolean;
var
  EnumHandle: THandle;
  BufSize: DWord;
  Res: DWord;
begin
  Result := False;
//  List := Nil;
  Entries := 0;
  if WNetOpenEnum(RESOURCE_GLOBALNET,
                  ResourceType,
                  0,
                  NetResource,
                  EnumHandle) = NO_ERROR then begin
    try
      BufSize := $4000; // 16 kByte
      GetMem(List, BufSize);
      try
        repeat
          Entries := DWord(-1);
          FillChar(List^, BufSize, 0);
          Res := WNetEnumResource(EnumHandle, Entries, List, BufSize);
       {   if Res = ERROR_MORE_DATA then
          begin
            ReAllocMem(List, BufSize);
          end;                      }
        until Res <> ERROR_MORE_DATA;

        Result := Res = NO_ERROR;
        if not Result then
        begin
          FreeMem(List);
          List := Nil;
          Entries := 0;
        end;
      except
        FreeMem(List);
        raise;
      end;
    finally
      WNetCloseEnum(EnumHandle);
    end;
  end;
end;

procedure ScanNetworkResources(ResourceType, DisplayType: DWord; List: TStrings);

procedure ScanLevel(NetResource: PNetResource);
var
  Entries: DWord;
  NetResourceList: PNetResourceArray;
  i: Integer;
begin
  if CreateNetResourceList(ResourceType, NetResource, Entries, NetResourceList) then try
    for i := 0 to Integer(Entries) - 1 do
    begin

      if (DisplayType = RESOURCEDISPLAYTYPE_GENERIC) or
        (NetResourceList[i].dwDisplayType = DisplayType) then begin
        If (Copy(NetResourceList[i].lpRemoteName,1,2)='\\') then
        Form1.ListBox1.Items.AddObject(NetResourceList[i].lpRemoteName, Pointer(NetResourceList[i].dwDisplayType));
      end;
      if (NetResourceList[i].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then
        ScanLevel(@NetResourceList[i]);
    end;
  finally
    FreeMem(NetResourceList);
  end;
end;

begin
  ScanLevel(Nil);
end;

end.
die ganzen schleifen (denke ich) machen die unit so lam....könnt ihr mir zeigen wie ihr das beschleunigen würdet.

FriFra 19. Dez 2005 08:23

Re: Tricks um Programm zu beschleunigen
 
lagere Die bettr. Funktionen doch "einfach" in einen Thread aus :-D

Luckie 19. Dez 2005 08:27

Re: Tricks um Programm zu beschleunigen
 
Der Flaschenhals in diesem Fall ist nicht der Code sondern die Hardware, bzw. um genau zu sein das Netzwerk. Schlechtes Beispiel. Nächstes Beispiel.

XeRo 19. Dez 2005 08:30

Re: Tricks um Programm zu beschleunigen
 
in einen thread hab ich es ja schon...siehe in einem anderen thread...

und was kann man machen wenn man DAS beschleunigen willt....genau darum gehts mir nämlich...in erster linie...

Bernhard Geyer 19. Dez 2005 08:31

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von Luckie
Der Flaschenhals in diesem Fall ist nicht der Code sondern die Hardware, bzw. um genau zu sein das Netzwerk. Schlechtes Beispiel. Nächstes Beispiel.

Würde ich nicht unbedingt sagen.
Wird der Code immer wieder aufgerufen?
Falls ja, was spricht dagegen das Ergebnis zu cachen und dann periodisch in einem Thread zu aktualisieren (wenn aktualisierung überhaupt so nötig ist)? Evtl. erst auf Knopfdruck mit Fortschrittsdialog.

Luckie 19. Dez 2005 08:45

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von XeRo
und was kann man machen wenn man DAS beschleunigen willt....genau darum gehts mir nämlich...in erster linie...

Gar nicht. Windows braucht eben so lange bis der Rechner im Netzwerk reagiert und die Struktur der API Funktion gefüllt hat.

XeRo 19. Dez 2005 09:24

Re: Tricks um Programm zu beschleunigen
 
sind schnellere Programme normalerweise größer als langsamere, oder kann man das so nicht sagen?

Luckie 19. Dez 2005 09:27

Re: Tricks um Programm zu beschleunigen
 
DFie Größe (Was auch immer für eine.) hat mit der Geschwindigkeit nichst zu tun. Sonst könnte man ja ein paar MB in die Ressourcen packen oder einfach ein paar MB Speicher sinnlos verbraten und es würde schneller. Dass das keinen Sinn macht sollte jedem klar sein.

XeRo 19. Dez 2005 09:37

Re: Tricks um Programm zu beschleunigen
 
nein...das mein ich ja so nicht...ich will wissen ob ein schnelleres script zwangsweiße größer ist als ein lames....
...damit drängt sich mir auch die frage auf ob komponenten unbedingt hilfreich sind....oder ob man wo möglich darauf verzichten sollte.

Luckie 19. Dez 2005 09:40

Re: Tricks um Programm zu beschleunigen
 
Ich sagte doch, die Größe, was auch immer, Codegröße in Byte, Anzahl der Zeilen, spielt keine Rolle. Wenn der Algorithmus oder was sonst noch eine Rolle spielt, einfach schlecht ist, dann kann der Code noch so groß oder klein sein, das ist vollkommen egal.

FriFra 19. Dez 2005 09:49

Re: Tricks um Programm zu beschleunigen
 
Luckie hat zwar im Prinzip recht, aber eigentlich auch wieder nicht...

Allgemein kann man sicher davon ausgehen, dass "schlankerer" Code auch schneller läuft. D.h., wenn man auf Komponenten verzichtet und alles "von Hand" macht, könnte es durchaus sein, dass der Code schneller läuft, da man dabei auf nicht benötigten Ballast (den bringen fertige Kompos meistens mit) verzichtet. Also, weniger Code -> schnellere Ausführung ... aber auch hier bestätigen Ausnahmen die Regel :zwinker:

Im konkreten Beispiel glaube ich aber kaum, dass da noch viel zu machen ist. Selbst wenn das Programm beim Neuzeichnen etwas gebremst wird, ist der Flaschenhals das Netzwerk. Da helfen nur schnellere Netzwerkkomponenten :lol:

HERMES 19. Dez 2005 10:06

Re: Tricks um Programm zu beschleunigen
 
Das mit der größe kann man so nicht sagen! Die Performance hängt nicht von der größe ab.

Zu deinem Beispiel, da kann man wirklich nicht ernsthafte verbesserungen erziehlen. Das hängt an Windows, durch einen Thread wirds auch nicht schneller, nur dein Hauptfenster hängt nicht.

Im algemeinen einfach versuchen das wachstum des Algorithmusses so gering wiemöglich zu halten, in deinem geht es nicht anders.

Naja, in wie weit schlanker code einen Algorithmus schneller macht, kann man nur wenn man ein und den selben algorithmus nimmt vergleichen.
Im wesentlichen kommt es auf die anzahl der Schleifendurchläufe an.
Hier ist es recht egal wie schlank oder auch nicht der Code ist, da es hier nicht um ein System geht, das Millionen ( nochnichtmal tausende ) von Datensätzen bearbeitet, sondern mit weniger als 100 durchläufen auskommt.


mfg
Sim

opfer.der.genauigkeit 19. Dez 2005 10:08

Re: Tricks um Programm zu beschleunigen
 
Schlankerer Code ist schneller? Höchstens doch in Zusammenarbeit mit Bibliotheken. Je weniger ich drumherum habe und desto direkter ich arbeite, desto mehr Effizenz kann ich erzeugen.
Wie FriFra schon mit "Ballast" erwähnte.
Aber "schlanker Code == schneller Code" würde ich so nicht verallgemeinert sagen.
Schlüßelwörter wie virtual und inline sorgen für Schnelligkeit auf Kosten der Größe.

HERMES 19. Dez 2005 10:13

Re: Tricks um Programm zu beschleunigen
 
Was soll das mit Virtual zu tun haben? Virtual ist schneller als Dynamic, ober nicht schneller als eine statische Mathode, die nicht überschrieben werden kann, weil da nicht erst nechgesehen werden muss welche jetzt eigentlich genommen werden soll und wo die steht.

opfer.der.genauigkeit 19. Dez 2005 10:19

Re: Tricks um Programm zu beschleunigen
 
Auszug aus der Hilfe:
Zitat:

Virtuelle und dynamische Methoden sind von der Semantik her identisch. Sie unterscheiden sich nur bei der Implementierung der Aufrufverteilung zur Laufzeit. Virtuelle Methoden werden auf Geschwindigkeit, dynamische Methoden auf Code-Größe optimiert.
Aus diesem Grund hatte ich das erwähnt. Vielleicht hätte ich static als Beispiel verwenden sollen, das wäre sicherlich eher angenommen worden.

HERMES 19. Dez 2005 10:28

Re: Tricks um Programm zu beschleunigen
 
Das hab ich ja nicht bestritten, allerdings, geht es hier nur darum, dass der aufruf einer statischen methode schneller ist der einer dymischen/ virtuellen. Bei der angesprochenen optimierung auf geschwindigkeit und größe, geht es nur um den AUFRUF nicht um die AUSFÜHRUNG. Die eigentliche ausfürhrung der Methoden ist gleich, denn der Inhalt der Methoden wird immer mit O3 ( ausser wenn in den Projektoptionen was anderes eingestellt ist) optimiert. O3 bedeutet maximale optimierung wobei auch eine vergrößerung des Codes zugunsten der Ausführungszeit in kauf genommen wird.

alzaimar 19. Dez 2005 10:54

Re: Tricks um Programm zu beschleunigen
 
Ihr redet hier von Optimierungen im Nachkommabereich.

Wenn es aber darum geht, ein Programm erstmal von 'lahm' (mit 'h') auf schnell (mit 'l' :zwinker: ) zu drehen, sollte man sich nicht darum kümmern, sondern um solche Sachen wie:
1. Algorithmen und deren Komplexität. Damit meine ich *nicht*, wie kompliziert ein Algorithmus ist, sondern sein Laufzeitverhalten ('big oh'). Der alte Satz stimmt immer noch, das ein Quicksort auf einem 8MHZ 8086 immer schneller ablaufen wird, als ein Bubblesort auf einer Cray (bildlich gesprochen). Gilt natürlich erst ab einer bestimmten Arraygröße. Das liegt daran, das Bubblesort vom Laufzeitverhalten bei doppelter Arraygröße 4x langsamer ist, ein Quicksort aber nur 1,3x langsamer.

Faustregel: Es gibt keine optimalen Algorithmen, deren Laufzeitverhalten > n^3 ist (Also 3 ineinander verschachtelte Schleifen). Matrizenmultiplikation ist ein Extrembeispiel, wo jedoch durch Tricks die Komplexität inzwischen bei ca. O(n^2.3) liegt.

2.Vermeidung von dynamischen Stringvariablen
Die Konkatenation von Strings, also a:= a+'Foo' ist ein Pferdefuss. Vergleiche mal:
Delphi-Quellcode:
Function LameConcat (aStrings : TStrings) : String;
Var
  i : Integer;

Begin
  Result :='';
  For i:=0 To aStrings.Count - 1 do
     Result := Result + aStrings[i];
End;
mit
Delphi-Quellcode:
Function FasterConcat (aStrings : TStrings) : String;
Var
  p, i, n : Integer;

Begin
  n := 0;
  For i:=0 To aStrings.Count - 1 do
    inc (n, Length (aStrings[i]);
  SetLength (Result, l);
  p := 1;
  For i:=0 To aStrings.Count - 1 do begin
    n := Length (aStrings[i]);
    System.Move (@aStrings[i][1], @Result[p], n);
    inc (p,n);
  End;
End;
Beide Funktionen sollen die Zeile einer Stringliste hintereinander packen und zurückliefern.
Code #1 hängt einfach die i.te Zeile an einen anfangs leeren String. Dabei wird bei jedem Anhängen neuer Speicher reserviert, der alte Teilstring reinkopiert und die Zeile hintendran gebeppt. Das verbraucht natürlich Zeit, nämlich umso mehr, je länger der String ist.
Code#2 rechnet erstmal aus, wieviel Platz von Nöten ist, reserviert den Platz einmalig und kopiert einfach die Zeilen hintereinander und ist damit, je nach Anzahl der Zeilen. ca. 20-100x schneller.

3. Vermeiden von unnötigen Visualisierungen.
Sobald man mit Listen/Datenmengen arbeitet, die in einem Formular visualisiert werden (Memo, Listbox, DBGrid etc.) sollte man die BeginUpdate/EndUpdate (bzw. DisableControls/EnableControls) Methoden verwenden.

4. Gute DBMS
Das ist ein Thema für sich.

5..999: Sachen, die ich vergessen habe

1000. Ab hier sind wir im einstelligen Prozentbereich und können dynamische und virtuelle Methoden analyieren.

Unterm Strich bleibt zu sagen, das mit dieser Thematik Bücherwände füllen könnte.

dizzy 19. Dez 2005 10:56

Re: Tricks um Programm zu beschleunigen
 
Zum Problem der Optimierung an und für sich:
Zunächst steht, wie oben bereits erwähnt, eine Analyse des Programmes an, durch die kritische Teile im Code ausfindig gemacht werden. Ein Profiler stellt hier die pragmatischte Variante dar, ein anderer Weg ist es für jede Zeile abzuschätzen wie viele CPU-Cycles für diese benötigt werden. (Das hinkt jedoch auch etwas, da eben andere Hardware ausgenommen wird, wie in deinem Fall z.B. das Netzwerk! Somit ist das eher was für arithmetische Algos.) Alles weitere ist nun absolut fallabhängig.

Ein klassischer Optimierungsfall ist z.B. die 2D Cosinunstransformation (die u.a. bei jpeg und mp3 zum Einsatz kommt). Ein rein von der mathem. Formel abgeleiteter Algo besitzt eine 3-fach Schleife in der mehrfach trigonometrische Operationen und andere Rechungen durchgeführt werden. Dies ist extrem lahm 8). Da man aber weiss, dass die 2D-Transformation auch berechnet werden kann, indem man erst alle Zeilen, und dann alle Spalten berechnet, kann man rein algorithmisch optimieren, nämlich zu 2 2-fach Schleifen. Damit spart man schon eine ganze Menge, da viele Teilrechnungen nicht mehr so oft redundant durchgeführt werden müssen. Nach und nach mit steigender Kenntnis des Algos, hat man soweit optimieren können, dass nunmehr eine Hand voll Multiplikationen und Additionen kombiniert mit wenigen vorberechneten Konstanten ausreichen. Verglichen mit dem ersten Algo hat man immens Gewinn gemacht.
Die Moral? Tja, das ist eben ganz speziell nur für diesen Fall zugeschnitten, da das Verfahren so ist wie es ist. Optimierung heisst in den meisten Fällen gleichzeitig auch Spezialisierung, und somit Konzentration auf genau diesen einen Fall. Und genau DAS macht es eigentlich unmöglich generelle Aussagen zur Optimierung zu machen.

Weniger Code = schneller?:
Eine Schleife z.B. ist immer minimal langsamer als alle Durchläufe aufgedröselt hintereinander weg geschrieben, da die Verwaltung der Schleife hinzu kommt, und meist auch Sprünge im Code (was aktuelle Jump Predictions der CPU jedoch mittlerweile ganz gut im Griff haben, so dass das Caching/Pipelining nicht mehr so leidet wie es mal war). Das ist idR nicht viel, aber es wiederlegt o.g. Aussage. Die Dynamik und Wartbarkeit leidet da allerdings doch etwas zu sehr, als dass sich das im entferntesten lohnen könnte ;)

Was deinen speziellen Fall hier angeht, da bist du tatsächlich an die Grenzen der Hardware/API gebunden. Irgendwo ist halt Schluss.


Gruss,
Fabian

Der_Unwissende 19. Dez 2005 11:09

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von dizzy
Die Moral? Tja, das ist eben ganz speziell nur für diesen Fall zugeschnitten, da das Verfahren so ist wie es ist. Optimierung heisst in den meisten Fällen gleichzeitig auch Spezialisierung, und somit Konzentration auf genau diesen einen Fall. Und genau DAS macht es eigentlich unmöglich generelle Aussagen zur Optimierung zu machen.

Geb ich dir Recht, aber eigentlich ist die Herangehensweise auch (fast) immer die gleiche. Man nennt es Dynamische Programmierung, man berechnet Zwischenergebnisse vor (kostengünstig) und mit diesen weiter und landet dann bei einer geringeren Laufzeit als bei einem Greedy-Algorithmus (also irgendeiner offensichtlichen Lösung). Das ist (wenn ich mich richtig erinnere) auch der Trick für Matrizenmultiplikation. Damit kommen wir häufig auch auf mehr Code, da gibt es doch diese effizientere Multiplikation zweier Komplexer Zahlen, da benötigt man deutlich mehr Additionen, aber weniger Multiplikationen, hat mehr Codezeilen und spart trotzdem Zeit (schon allein weil eine Multiplikation "teurer" ist als ein Addition).

Wie hier schon zu genüge gesagt wurde, es geht nicht wirklich ohne Profiler. Aber am wichtigsten, an den wenigsten Stellen bringt Optimierung etwas. Natürlich kannst du dich totoptimieren an fast jedem Code und da wirklich ordentlich was rausholen und der Benutzer würde es nicht in Ansätzen merken. Das liegt dann einfach daran, dass die 80/20 Regel greift, 80% der Dinge die mit der Software gemacht werden, entsprechen gerade einmal 20% der Funktionen. Wenn du etwas optimieren möchtest, sollte es also tunlichst in diesen 20% liegen, da sonst die Kosten für eine Optimierung sämtlichen Nutzen übersteigen dürften (auch hier gilt eher 80/20, nicht immer).

Gruß Der Unwissende

Jasocul 19. Dez 2005 11:24

Re: Tricks um Programm zu beschleunigen
 
Es gibt bei mir zwei Dinge, die ich immer wieder bei der Programmierung bedenke:
1. Fehlerbehandlung selbst übernehmen. Try..Except ist eine Todesfalle schnellen Code.
2. Keine Visualisierung von automatischen Abläufen. Zumindest auf das nötigste beschränken.

Ein paar andere Dinge gibt es auch noch, die man beachten sollte, werden aber nicht so regelmäßig notwendig sein:
- Möglichst selten Daten nachladen (DB- und Dateizugriffe sind langsamer als Speicherzugriffe)
- Nur da optimieren, wo es sind macht: Im Dialog mit dem Anwender ist das nahezu sinnlos. Der Anwender ist bestimmt langsamer.
- In langsamen Routinen mehr Werte zwischenspeichern. Dann müssen diese nicht immer wieder neu berechnet werden.
- Vor Allem Schleifen prüfen, ob dort immer wieder das selbe berechnet wird. Passiert oft bei Stringvergleichen mit der Pos-Funktion, um nur ein Beispiel zu nennen.

Alles andere sind Spezial-Dinge, die im Einzelnen untersucht werden müssen.

mumu 19. Dez 2005 12:33

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Fehlerbehandlung selbst übernehmen. Try..Except ist eine Todesfalle schnellen Code.
soweit ich aber weiß ist das jedoch nur beim debug zeitpunkt so. in der runtime umgebung sollte ein try except nicht wirklich sehr performance schädigend sein, oder? ich mein der stack, lokale Variablen, und weitere informationen werden bei einer exception bei debuggen gesammelt und deshalb ist hier das programm langsamer, oder?

bigg 19. Dez 2005 12:35

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von XeRo
ich geb mal mein konkretes beispiel:

unit stammt von Florian Bernd
Delphi-Quellcode:
unit ActiveConnections;

interface

uses windows, classes, Unit1;

procedure ScanNetworkResources(ResourceType, DisplayType: DWord; List: TStrings);

implementation

type
  PNetResourceArray = ^TNetResourceArray;
  TNetResourceArray = array[0..100] of TNetResource;



function CreateNetResourceList(ResourceType: DWord;
                              NetResource: PNetResource;
                              out Entries: DWord;
                              out List: PNetResourceArray): Boolean;
var
  EnumHandle: THandle;
  BufSize: DWord;
  Res: DWord;
begin
  Result := False;
//  List := Nil;
  Entries := 0;
  if WNetOpenEnum(RESOURCE_GLOBALNET,
                  ResourceType,
                  0,
                  NetResource,
                  EnumHandle) = NO_ERROR then begin
    try
      BufSize := $4000; // 16 kByte
      GetMem(List, BufSize);
      try
        repeat
          Entries := DWord(-1);
          FillChar(List^, BufSize, 0);
          Res := WNetEnumResource(EnumHandle, Entries, List, BufSize);
       {   if Res = ERROR_MORE_DATA then
          begin
            ReAllocMem(List, BufSize);
          end;                      }
        until Res <> ERROR_MORE_DATA;

        Result := Res = NO_ERROR;
        if not Result then
        begin
          FreeMem(List);
          List := Nil;
          Entries := 0;
        end;
      except
        FreeMem(List);
        raise;
      end;
    finally
      WNetCloseEnum(EnumHandle);
    end;
  end;
end;

procedure ScanNetworkResources(ResourceType, DisplayType: DWord; List: TStrings);

procedure ScanLevel(NetResource: PNetResource);
var
  Entries: DWord;
  NetResourceList: PNetResourceArray;
  i: Integer;
begin
  if CreateNetResourceList(ResourceType, NetResource, Entries, NetResourceList) then try
    for i := 0 to Integer(Entries) - 1 do
    begin

      if (DisplayType = RESOURCEDISPLAYTYPE_GENERIC) or
        (NetResourceList[i].dwDisplayType = DisplayType) then begin
        If (Copy(NetResourceList[i].lpRemoteName,1,2)='\\') then
        Form1.ListBox1.Items.AddObject(NetResourceList[i].lpRemoteName, Pointer(NetResourceList[i].dwDisplayType));
      end;
      if (NetResourceList[i].dwUsage and RESOURCEUSAGE_CONTAINER) <> 0 then
        ScanLevel(@NetResourceList[i]);
    end;
  finally
    FreeMem(NetResourceList);
  end;
end;

begin
  ScanLevel(Nil);
end;

end.
die ganzen schleifen (denke ich) machen die unit so lam....könnt ihr mir zeigen wie ihr das beschleunigen würdet.

Was macht der Code denn überhaupt?

Jasocul 19. Dez 2005 12:44

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von mumu
Zitat:

Fehlerbehandlung selbst übernehmen. Try..Except ist eine Todesfalle schnellen Code.
soweit ich aber weiß ist das jedoch nur beim debug zeitpunkt so. in der runtime umgebung sollte ein try except nicht wirklich sehr performance schädigend sein, oder? ich mein der stack, lokale Variablen, und weitere informationen werden bei einer exception bei debuggen gesammelt und deshalb ist hier das programm langsamer, oder?

Auch zur Laufzeit ein echtes Problem. Weiß ich aus leidvoller, eigener Erfahrung. Besonders schlimm wird es, wenn die Exception auch noch regelmäßig ausgelöst wird.

alzaimar 19. Dez 2005 13:22

Re: Tricks um Programm zu beschleunigen
 
Ich will Dir ja nicht widersprechen, aber so gewaltig sind die Unterschiede nicht:
Delphi-Quellcode:
Var
  c,i : Cardinal;
  r : Real;

begin
  c := getTickCount;
  r := 0;
  For i:=1 to 20000000 do r:=r+r/i;
  memo.Lines.Add(intToStr (GetTickcount - c));
  c := getTickCount;
  r := 0;
  For i:=1 to 20000000 do try r:=r+r/i; except end;
  memo.Lines.Add(intToStr (GetTickcount - c));
end;
ergibt bei mir hier 500 und 620 (ca.) Ticks... Ob da was wegoptimiert wird, weiss ich nicht.

Allerdings, da geb ich Dir Recht, kommt man irgendwann dahin, das die 20% Performanceunterschied ein echtes Erfolgserlebnis sind: Wenn nämlich sonst kaum noch was rauszuholen ist.

mumu 19. Dez 2005 13:47

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von alzaimar
Ich will Dir ja nicht widersprechen, aber so gewaltig sind die Unterschiede nicht:
Delphi-Quellcode:
Var
  c,i : Cardinal;
  r : Real;

begin
  c := getTickCount;
  r := 0;
  For i:=1 to 20000000 do r:=r+r/i;
  memo.Lines.Add(intToStr (GetTickcount - c));
  c := getTickCount;
  r := 0;
  For i:=1 to 20000000 do try r:=r+r/i; except end;
  memo.Lines.Add(intToStr (GetTickcount - c));
end;
ergibt bei mir hier 500 und 620 (ca.) Ticks... Ob da was wegoptimiert wird, weiss ich nicht.

Allerdings, da geb ich Dir Recht, kommt man irgendwann dahin, das die 20% Performanceunterschied ein echtes Erfolgserlebnis sind: Wenn nämlich sonst kaum noch was rauszuholen ist.

naja so in etwa hätte ich mir das auch vorgestellt. exceptions sind zwar (meiner meinung nach, die Indys haben da ja eine andere Meinung) unsaubere Programmierung und sollten eigentlich wirklich nur bei gravierenden Fehlern auftauchen, jedoch zur runtime nicht sehr performance schädigend.

alzaimar 19. Dez 2005 14:56

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von mumu
exceptions sind zwar (meiner meinung nach, die Indys haben da ja eine andere Meinung) unsaubere Programmierung und sollten eigentlich wirklich nur bei gravierenden Fehlern auftauchen...

Wieso? Irgendwie muss man ja falsche Parameter ('Design by contract') ablehnen.
Variante A: Die Routinen liefern True, wenn alles im Lot sind und False sonst.
Delphi-Quellcode:
If EineProcedure Then
  If DieNaechsteProcedure Then
    If NochEineProcedure Then
      If EndlichDieLetzteProcedure Then
         Output ('Alles ok')
      else
        Output ('Hupsa')
    else
      Output ('Hupsa')
  else
    Output ('Hupsa')
else
  Output ('Hupsa');
Variante B: Die Routinen erzeugen eine Exception wenn irgendwas faul ist:
Delphi-Quellcode:
Try
  EineProcedure;
  DieNaechsteProcedure;
  NochEineProcedure;
  EndlichDieLetzteProcedure;
  Output ('Alles ok');
Except
  Output ('Hupsa');
End;
Also, ich finde 'B' übersichtlicher. Das einzige, was nervt, ist das Debuggen. Aber wenn man die Prozeduren spezielle Exceptions ('EMyException') auslösen lässt, kann man die auch wegfiltern.

Aber zurück zum Thema...

Jasocul 19. Dez 2005 15:10

Re: Tricks um Programm zu beschleunigen
 
Dann testet doch mal eure Routinen, indem ihr alle 1000 Durchläufe eine Exception auslöst. Das dürfte ganz erhebliche Performance einbußen bringen. Baut doch einfach mal eine Division durch Null ein:
Delphi-Quellcode:
Var
  c,i : Cardinal;
  r : Real;

begin
  c := getTickCount;
  r := 0;
  For i:=1 to 20000000 do
  begin
    if (i div 1000) = (i/1000) then
      r := r
    else
      r:=r+r/i;
  end;
  memo.Lines.Add(intToStr (GetTickcount - c));
  c := getTickCount;
  r := 0;
  For i:=1 to 20000000 do
  begin
    try
      if (i div 1000) = (i/1000) then
        r := r / 0;
      else
        r:=r+r/i;
    except
    end;
  end;
  memo.Lines.Add(intToStr (GetTickcount - c));
end;
Habe das jetzt nicht bei mir geprüft, aber das Ergebnis sollte deutlich sein.

@alzaimar:
Hier gehts doch nicht um Übersichtlichkeit. :lol:

tigerman33 19. Dez 2005 15:14

Re: Tricks um Programm zu beschleunigen
 
Also letztendlich muss man ja des öfteren eine Entscheidung zwischen übersichtlichem Code und maximaler Geschwindigkeit treffen. Und bei exceptions nehme ich da Geschwindigkeitseinbußen gerne in Kauf.

Und Code, der mit der von dir beschriebenen Regelmäßigkeit Exceptions auslöst, macht IMHO sowieso was falsch. "Exception" heißt ja nicht umsonst "Ausnahme", und als solche sollte sie auch verstanden werden, nicht als reguläres Kommunikationsmittel. Dafür gibt es andere (schnellere!) Varianten.

// edit:
Zitat:

Hier gehts doch nicht um Übersichtlichkeit.
Vielleicht nicht direkt, im Kontext aber schon. Denn beim "Wegoptimieren" sollte man sich schon überlegen, ob der Geschwindigkeitsvorteil es jetzt tatsächlich wert ist, solchen Spaghetticode wie die verschachtelten Aufrufe (s.o.) in Kauf zu nehmen.

BTW: Wer kann denn einen einfach zu bedienenden (Freeware-)Profiler empfehlen? :?:

mumu 19. Dez 2005 15:17

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von alzaimar
Zitat:

Zitat von mumu
exceptions sind zwar (meiner meinung nach, die Indys haben da ja eine andere Meinung) unsaubere Programmierung und sollten eigentlich wirklich nur bei gravierenden Fehlern auftauchen...

Wieso? Irgendwie muss man ja falsche Parameter ('Design by contract') ablehnen.
Variante A: Die Routinen liefern True, wenn alles im Lot sind und False sonst.
Delphi-Quellcode:
If EineProcedure Then
  If DieNaechsteProcedure Then
    If NochEineProcedure Then
      If EndlichDieLetzteProcedure Then
         Output ('Alles ok')
      else
        Output ('Hupsa')
    else
      Output ('Hupsa')
  else
    Output ('Hupsa')
else
  Output ('Hupsa');
Variante B: Die Routinen erzeugen eine Exception wenn irgendwas faul ist:
Delphi-Quellcode:
Try
  EineProcedure;
  DieNaechsteProcedure;
  NochEineProcedure;
  EndlichDieLetzteProcedure;
  Output ('Alles ok');
Except
  Output ('Hupsa');
End;
Also, ich finde 'B' übersichtlicher. Das einzige, was nervt, ist das Debuggen. Aber wenn man die Prozeduren spezielle Exceptions ('EMyException') auslösen lässt, kann man die auch wegfiltern.

Aber zurück zum Thema...

ja alzaimar, das kann schon sein, aber ich hab ja geschrieben, dass das meine persönliche meinung ist mit den exceptions. ich find das einfach unschön bei sachen die man anders abfangen kann und im vornherrein bedacht hat, exceptions auslösen zu lassen.

naja muss im endeffekt jeder selbst wissen, ich finds aber schöner ohne exceptions, weil wenn nämlich dann welche auftreten, dann weiß ich bei meinem code 100 pro, dass ich da irgendwas nicht bedacht habe.

cruso 19. Dez 2005 15:20

Re: Tricks um Programm zu beschleunigen
 
Noch ein Tipp um ein Programm schnell zu halten:
Möglichst wenige Timer einbauen, da zu viele Timer das Programm ausbremsen (was vor allem am Betriebssystem liegt). Also nur wenige Timer (nur einen oder wenn möglich keinen) in das Programm integrieren!

MfG
Cruso

Jasocul 19. Dez 2005 15:29

Re: Tricks um Programm zu beschleunigen
 
Zitat:

Zitat von tigerman33
Und Code, der mit der von dir beschriebenen Regelmäßigkeit Exceptions auslöst, macht IMHO sowieso was falsch. "Exception" heißt ja nicht umsonst "Ausnahme", und als solche sollte sie auch verstanden werden, nicht als reguläres Kommunikationsmittel. Dafür gibt es andere (schnellere!) Varianten.

Das war der Grund, warum ich schon vorher irgendwann mal geschrieben hatte, dass man die Fehlerbehandlung selbst übernehmen sollte und nicht mit Exception-Handling. Natürlich kann man es trotzdem für unerwartete Fehler verwenden. Das mache ich auch. Aber in Schleifen damit zu arbeiten und Fehler einzuplanen, um diese in einer Exception abzuarbeiten ist ungeschickt. Das ist aber ein "typischer" Anfängerfehler: "Exceptions sind Klasse. Man braucht sich um nichts mehr kümmern...".
Darum so ausführlich.

alzaimar 19. Dez 2005 16:22

Re: Tricks um Programm zu beschleunigen
 
(Mein) letztes Wort zu exceptions, den Ausnahmen: Da sie ausnahmsweise auftreten, kann man die Geschwindigkeitseinbußen, die dann auftreten, ruhig in Kauf nehmen. jasoculs Code weiter oben zeigt, das eine einzelne Exception ca. doppelt so langsam wie die Abfrage per Hand ist.

Grundsätzlich ist klar, das man Exceptionbehandlung nicht zur Flusskontrolle nehmen sollte, also z.B. so (aber nicht lachen)
Delphi-Quellcode:
Done := False;
Repeat
  Try
    DoSomething;
    If Finished Then Abort;
  Except
    Done := True;
  End;
Until Done;
Nebenbei: Mein Beispielcode sollte doch nur mal demonstrieren, das der Overhead einer Try-Finally Behandlung bei ca. 20% liegt, wenn's *nicht* schiefgeht. Da man Exceptions ja für die Ausnahmen (ja Alz, das wissen wir jetzt :stupid: ) verwendet, kann man die imho ruhigh im Code lassen, da es die Performance naturgemäß nur marginal beeinflusst.

Gott-Sei-Dank spielt die Programmiersprache (der alte K(r)ampf Delphi vs. C) beim Optimieren keine Rolle mehr. Nur Assembler bringt bei bestimmten rechenintensiven Geschichten noch die eine oder andere Sekunde, aber dann ist auch Schluss.

Ich kann jedem nur empfehlen, ein Gefühl für die Komplexität eines Verfahrens zu bekommen. Oben erwähntes Beispiel für die JPEG-Berechnung zeigt, das man mit 1x Nachdenken Berge versetzen kann.

Einen Punkt (ca. 10% Gewinn) hab ich noch: Rekursion vermeiden.

Ein hübsches Beispiel, wie im Team ein Problem performancetechnisch eingedampft werden kann, zeigt dieser Thread: Es ging um Primzahlen.
http://www.delphi-forum.de/viewtopic...er=asc&start=0

Hier gings um Stringkonvertierungen:
http://www.delphi-forum.de/viewtopic.php?t=46537

Und hier ums Sortieren von GB großen Textdateien:
http://www.delphi-forum.de/viewtopic...718&highlight=

So, zum Schmöckern...


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:43 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