Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi NonVCL Version von Classes.dcu (https://www.delphipraxis.net/13413-nonvcl-version-von-classes-dcu.html)

scp 18. Dez 2003 11:24

Re: NonVCL Version von Classes.dcu
 
Folgender Erweiterungsvorschlag für TStrList:

1. Die Funktion Strings in GetStr und Replace in SetStr umbenennen.
2. Die beiden Functionen in den protected Bereich verschieben.
3. Folgende Zeile ans Ende der public-Deklarition einfügen:

Delphi-Quellcode:
    property Strings[Index : Integer] : String read GetStr write SetStr; default;
Somit hat man mit ein bißchen Code ein Stück mehr das Verhalten von TStringList / TStrings.

OLLI_T 18. Dez 2003 13:19

Re: NonVCL Version von Classes.dcu
 
Da sind aber viele Fehler drin in dieser Klasse TStrList ... :gruebel:

scp 18. Dez 2003 13:57

Re: NonVCL Version von Classes.dcu
 
Zitat:

Zitat von OLLI_T
Da sind aber viele Fehler drin in dieser Klasse TStrList ... :gruebel:

Na, dann leg mal los. Ich hab sonst nix aussergewöhnliches gesehen. "Viele Fehler" ist ja nicht gerade eine hilfreiche Aussage.

Luckie 18. Dez 2003 14:00

Re: NonVCL Version von Classes.dcu
 
Zitat:

Zitat von scp
Zitat:

Zitat von OLLI_T
Da sind aber viele Fehler drin in dieser Klasse TStrList ... :gruebel:

Na, dann leg mal los. Ich hab sonst nix aussergewöhnliches gesehen. "Viele Fehler" ist ja nicht gerade eine hilfreiche Aussage.

Und bitte besser machen. :zwinker:

jbg 18. Dez 2003 16:48

Re: NonVCL Version von Classes.dcu
 
Zitat:

Zitat von Luckie
Jedes mal, wenn du was hinzufügst (Methode Add) verlängerst du das Array um eins und fügst den String dort ein.

Na dann viel Spaß mit dem sagenhaft geringen Speicherverbrauch von 200 MB für 5000 Elemente vom Typ Integer.

Luckie 18. Dez 2003 16:58

Re: NonVCL Version von Classes.dcu
 
War ja auch nur die einfache Version. Dass dies Speichertechnisch eigentlich Selbstmord ist, hätte ich noch erwähnen sollen. Aber in der hier geposteten Unit wird es nicht anders gemacht.

scp 18. Dez 2003 17:06

Re: NonVCL Version von Classes.dcu
 
Zitat:

Zitat von jbg
Zitat:

Zitat von Luckie
Jedes mal, wenn du was hinzufügst (Methode Add) verlängerst du das Array um eins und fügst den String dort ein.

Na dann viel Spaß mit dem sagenhaft geringen Speicherverbrauch von 200 MB für 5000 Elemente vom Typ Integer.

Ich weis zwar jetzt nich genau worauf du hinaus willst, aber die hier dargestellte TStrList unterscheidet sich kaum vom Original.
Auch bei der Borlandschen Version wird ein array verwendet, nur ist dies halt eine andere Art dynamisches Array:
Delphi-Quellcode:
  PStringItemList = ^TStringItemList;
  TStringItemList = array[0..MaxListSize] of TStringItem;
Es ist also zunächst eine statische Array, die aber nur den gerade nötigen Teil für die Anzahl Items per ReAllocMem() zugewiesen bekommt. Dies benötigt aber ebenfalls pro Element einen Integer-Wert (eigentlich ja Pointer), also 4 Byte + die Stringdaten.

PS: 5000 * 4 Byte sind doch 20000 Byte ~ 19,5 KB, oder wie meinst du das?

Chewie 18. Dez 2003 17:28

Re: NonVCL Version von Classes.dcu
 
Bei jedem Aufruf von SetLength wird das ganze Array an eine andere Speicherstelle verschoben, da nicht sicher ist, ob hinter der aktuellen Stelle noch genügend Platz dafür ist.
Durch irgendeine Schwäche im Delphi-Speichermanager (genaueres weiß ich auch nicht, würde mich auch mal interessieren) kann es nun passieren (und es passiert), dass der Speicher, den das Array vor dem Verschieben belegte, nicht wieder frei gegeben wird. Dadurch kommt die hohe Speicherbelastung zu Stande.
Daneben ist es natürlich auch höchst in effizient, wenn ständig Massen von Daten rumgeschoben werden, nur weil ein neuer String dazukommz.

jbg 18. Dez 2003 17:34

Re: NonVCL Version von Classes.dcu
 
Zitat:

Zitat von scp
aber die hier dargestellte TStrList unterscheidet sich kaum vom Original.

Aber das bisschen ist schon sehr ausschlaggebend.

Zitat:

Auch bei der Borlandschen Version wird ein array verwendet, nur ist dies halt eine andere Art dynamisches Array:
Das ist nicht das Problem.


Zitat:

5000 * 4 Byte sind doch 20000 Byte ~ 19,5 KB, oder wie meinst du das?
Theoretisch werden die 20000 Bytes auch nur reserviert. Praktisch wird Windows aber der Speicher in nicht geringen Mengen entzugen.


Zitat:

Es ist also zunächst eine statische Array, die aber nur den gerade nötigen Teil für die Anzahl Items per ReAllocMem() zugewiesen bekommt. Dies benötigt aber ebenfalls pro Element einen Integer-Wert (eigentlich ja Pointer), also 4 Byte + die Stringdaten.
Um es mal übertrieben darzustellen: Mit dieser Technik mishandelst du den Speichermanager von Delphi, der es dir dann mit einem Speicherbedraf gegen unendlich heimzahlt.

Bei jedem SetLength(a, Length(a) + 1) wird ein neuer Speicherbereich reserviert, die Daten kopiert und der alte als "Frei" vermerkt, also nicht an Windows zurückgegeben, da er später wieder benutzt werden könnte und somit schneller bereit steht, als wenn er erst bei Windows angefordert werden muss. Kommt nun die nächste Vergrößerung, so muss der Speichermanager wieder einen neuen Speicherbereich bei Windows reservieren, da das nun größere Array nicht in einen zuvor reservierten Speicher passt ...

Darum ist es besser, wenn man das Array einmalig auf die End-Länge setzt, anstatt jedesmal eins zur Länge hinzuzuaddieren. Man spart sich auch das ständige Kopieren des Arrays und gewinnt neben Speicherplatz auch an Geschwindigkeit.
Delphi-Quellcode:
var
  i: Integer;
  a: array of Integer;
begin
  ShowMessage('Start - Speicherschlucken');
  a := nil;
  for i := 0 to 99999 do
  begin
    SetLength(a, Length(a) + 1);
    a[i] := i;
  end;
  ShowMessage('Ende');
end;
Delphi-Quellcode:
var
  i: Integer;
  a: array of Integer;
begin
  ShowMessage('Start - Schneller und Speicherschonend');
  SetLength(a, 100000);
  for i := 0 to 99999 do
    a[i] := i;
  ShowMessage('Ende');
end;

scp 18. Dez 2003 17:35

Re: NonVCL Version von Classes.dcu
 
@chewie
Ersteres kann ich ja verstehen, wenn dem so ist, ist das natürlich ineffizient.

Aber das Massen von Daten verschoben werden, finde ich nicht so schlimm, es sind hier ja bei dem Bespiel mit den 5000 Elementen nur die 20 KB, was ja heutzutage nicht viel ist, die Daten der Strings bleiben ja unangetastet, weil es ja für jeden String einen Extra-Pointer/-Referenzzähler gibt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:41 Uhr.
Seite 2 von 3     12 3      

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