AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Tricks um Programm zu beschleunigen
Thema durchsuchen
Ansicht
Themen-Optionen

Tricks um Programm zu beschleunigen

Ein Thema von XeRo · begonnen am 19. Dez 2005 · letzter Beitrag vom 19. Dez 2005
Antwort Antwort
Seite 3 von 4     123 4      
opfer.der.genauigkeit

Registriert seit: 14. Feb 2005
66 Beiträge
 
#21

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 11:08
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.
Stellen Sie sich bitte Zirkusmusik vor.
  Mit Zitat antworten Zitat
HERMES

Registriert seit: 29. Nov 2004
142 Beiträge
 
#22

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 11:13
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.
  Mit Zitat antworten Zitat
opfer.der.genauigkeit

Registriert seit: 14. Feb 2005
66 Beiträge
 
#23

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 11:19
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.
Stellen Sie sich bitte Zirkusmusik vor.
  Mit Zitat antworten Zitat
HERMES

Registriert seit: 29. Nov 2004
142 Beiträge
 
#24

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 11:28
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.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#25

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 11:54
Ihr redet hier von Optimierungen im Nachkommabereich.

Wenn es aber darum geht, ein Programm erstmal von 'lahm' (mit 'h') auf schnell (mit 'l' ) 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.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#26

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 11:56
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
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#27

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 12:09
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
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.354 Beiträge
 
Delphi 11 Alexandria
 
#28

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 12:24
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.
Peter
  Mit Zitat antworten Zitat
mumu

Registriert seit: 28. Okt 2003
Ort: Bamberg
519 Beiträge
 
#29

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 13:33
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?
  Mit Zitat antworten Zitat
bigg
(Gast)

n/a Beiträge
 
#30

Re: Tricks um Programm zu beschleunigen

  Alt 19. Dez 2005, 13:35
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?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:31 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz