Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#7

Re: FastMM grotten langsam ?!

  Alt 4. Nov 2005, 03:41
Zitat von stoxx:
es ist natürlich so, dass ich nur die Hälfte von dem verstehe, was Du schreibst, da ich bei Speichermanagern nicht wirklich so der Fachmann bin.
FastMM ist bei Verwendung von TList im obigen Beispiel etwa 10 Prozent schneller als Delphi.
Der Vorteil verschwindet aber, wenn FastMM bei anderen Anwendungsfällen gleich um das Doppelte einen Ausreißer ins Negative hat.
Eigentlich sollte es nicht so sein, daß die Speicherverwaltung in einigen Fällen extrem verlangsamt wird.
Obwohl es natürlich möglich wäre, daß eine Verlangsamung auf Grund der anderen Art der Speicherverwaltung auftritt. (es wird halt etwas mehr gerechnet, um so optimaler zu arbeiten)

Obwohl ich nicht hoffe, daß es auch bei meinem MM so ist ._. (hast du es auch mal damit versucht)
Und wenn, würde ich mir dieses Verhalten, bei Zeiten, nochmals genauer ansehn und prüfen was sich da machen ließe ^^


Zitat von stoxx:
das wäre jetzt irgendwie interessant. und was bedeutet das ? .. hehe
Im Grunde ist es so, daß man (im Moment nur bei den Stringfunktionen meines UCCs) zusätzlich angeben kann in welchen Intervallen die Speicherreservierung für Strings arbeiten soll.

Dazu gibt es dann folgende Konstanten:
Delphi-Quellcode:
Type SLType = Type LongInt; // The OLE-WideString supported only slReal and slUnique is always set.

Const slReal = ...;
  slUpDown_1 = ...; slOnlyUp_1 = ...; // 0,1 KB / 128 B
  slUpDown = ...; slOnlyUp = ...; // 1 KB / 1024 B
  slUpDown10 = ...; slOnlyUp10 = ...; // 10 KB / 16384 B
  slUpDown100 = ...; slOnlyUp100 = ...; // 100 KB / 131072 B
  slUpDown1M = ...; slOnlyUp1M = ...; // 1 MB / 1048576 B

  slSetNew = ...;
  slZeroNew = slSetNew or Ord(#0);
  slSpaceNew = slSetNew or Ord(' ');

  slUnique = SLType($00200000);
//slThreadSave = SLType($00800000);
Mit slReal (ist natürlich der Standard, wenn man nichts angibt) bleibt alles so wie es bisher ist.
Über slUpDown... wird der Speicher immer nur in Schritten eines bestimmten Wertes reserviert und mit den slOnlyUp... kann zusätzlich noch verhindert werden, daß Speicher freigegeben/verkleinert wird.

Wenn man z.B. einen String hat, dessen Größe sich sehr oft (vorzugsweise in kurzer Zeit) über einen weiten Bereich verändert, dann kann man z.B. über die Angabe von slOnlyUp1M dafür sorgen, daß tatsächlich ständig Speicher freigegeben und reserviert wird. (einzig bei S := ''; oder einem SetLength auf 0 wird immer der Speicher, unabhängig vom Parameter, freigegeben, dieses hängt aber mit der Definition der Strings zusammen)
Es ist ja so, daß die Fast(X)MM vorwiegend ihre Vorteile nur bei kleiner Veränderungen können und bei "extrem" Großen nicht verbessern ausspielen.

Es haben alle alle Funktionen/Prozeduren zur Stringbehandlung (wenn es erforderlich ist) einen weiteren Parameter. (was ich ja auf weitere Bereich ausweiten möchte)
z.B.
Procedure _SetLength(Var S: AnsiString; Len: LongInt; Typ: SLType = slReal); Abgesehn davon hab ich mir auch noch weitere Optimierungen einfallen lassen, was das Tempo steigern kann
z.B.
Delphi-Quellcode:
Function _StringReplace(Const S, OldPattern, NewPattern: AnsiString; Flags: TReplaceFlagsEx; Typ: SLType = slReal): AnsiString;
Procedure StringReplaceV(Var S: AnsiString; Const OldPattern, NewPattern: AnsiString; Flags: TReplaceFlagsEx; Typ: SLType = slReal);
Zweiteres wird also schneller sein, da dort nach der Funktion nich erst der als String freigegeben und durch den Neuen ersetzt werden muß, da ja der String direkt verändert wird.
Delphi-Quellcode:
S := _StringReplace(S, 'alt', 'neu', [rfeReplaceAll]);
StringReplaceV(S, 'alt', 'neu', [rfeReplaceAll]);


Zitat von stoxx:
Eine Sache hab ich bei den Speichermanagern noch nicht verstanden, wenn ich ein Dynamisches Array habe, ist dieser Speicher auch wirklich dann zusammenhängend ?
Also, die Daten in einen Array sind immer zusammenhängend, man kann sich also ohne Probleme z.B. einen Pointer auf des ersten Eintrag, oder einen anderen besorgen und dann ohne weiteres auf die darauffolgenden, oder eventuell auch vorherige Einträge direkt zugreifen,, da sie ja wirklich im Speicher genau hintereinander liegen (mal abgesehn davon, das Aufgrund der Speicherausrichtung die Elemente in einem anderem Abstand angeordnet sind, siehe PACKET).
Es muß also Aufgrund der zsammenhängenden Datenstruktur immer ein zusammenhängender Speicherbereich reserviert werden.
Und zumindestens Fast(X)MM versuchen zuerst den nachfolgenden Speicher zu reservieren und wenn dieser schon belegt ist, dann muß halt der gesamte Speicher (z.B. die Arraydaten) verschoben/kopiert werden.

PS: die Listen verbrauchen ja nicht nur durch die vielen Zeiger mehr Platz. Es muß ja auch (unter Umständen, weiß ja nicht wie alle Listen arbeiten) für die einzelnen Elemente ein eigener Speicherbereich reserviert werden und pro Speicherbereich werden ja auch noch bestimmte Verwaltungsdaten (im MemoryManager) benötigt.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat