Delphi-PRAXiS

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 VirtualTree und MemoryStream (https://www.delphipraxis.net/165088-virtualtree-und-memorystream.html)

DelTurbo 14. Dez 2011 16:05

VirtualTree und MemoryStream
 
Ich möchte meinen Tree den ich erzeugt habe (ca. 17MB) abschpeichern. Ich mache das mit SaveToStream da ich danach die daten noch im speicher Zippe.

Nun ist mir aufgefallen das ein SaveToFile ca. 3 mal schneller ist. Eigentlich müsste doch Memory schneller sein, oder irre ich mich? Oder gibt es einen Trick dafür?

Gemessen habe ich natürlich nur SaveToMemory und SaveToFile. Ich habe zip oder sonstwas NICHT mitgemessen.

Danke im voraus

PS.: So, ich habe nun mal den MemoryStream auf 20MB gesetzt mit SetSize. Dann geht es ruckzuck. Nun bleibt die frage, wie bekomme ich vor dem Speichern die grösse vom VirtualTree raus?

himitsu 14. Dez 2011 16:31

AW: VirtualTree und MemoryStream
 
Zitat:

Zitat von DelTurbo (Beitrag 1141363)
Nun bleibt die frage, wie bekomme ich vor dem Speichern die grösse vom VirtualTree raus?

Indem du es vorher testweise abspeicherst?

Du könnstes dir einen TMemoryStream ableiten und dort das SetSize (automatische Vergrößerung) so optimieren, daß es nicht für jedem kleinen Schreibzugriff macht, sondern auch gleich mehr reserviert.


PS: Neueres Delphi kaufen (dort ist das schon drin) oder FastMM nutzen.

Das ist nicht nur schneller, sondern hat soeine Funktion schon eingebaut, samt InplaceRealloc, so daß nicht bei jeder kleinen Größenänderung der gesamte Speicherblock kopiert wird.

DelTurbo 14. Dez 2011 16:44

AW: VirtualTree und MemoryStream
 
FastMM hab ich drinne. Ich konnte da keinerlei veränderung feststellen. Ich dachte es gibt eine funktion wo man den Tree frage kann wie gross er ist. Aber ich habe nix gefunden. Schade...

himitsu 14. Dez 2011 18:01

AW: VirtualTree und MemoryStream
 
Du kannst ja grob schätzen?

Größe = Anzahl der Knoten * MagischeZahl



Aber statt Size würde ich eher das geheime Capacity setzen, oder du mußt den Stream, am Ende des Schreibvorgangs vom Tree, auf die korrekte Größe setzen.
Delphi-Quellcode:
MS.Size := 666;
VT.SaveToStream(MS);
MS.Size := MS.Position;
Delphi-Quellcode:
type
  TMemoryStreamHack = class(TMemoryStream)
    property Capacity;
  end;

TMemoryStreamHack(MS).Capacity:= 666; // oder direkt den Stream über diese Klasse erzeugen
VT.SaveToStream(MS);
Aber paß auf, daß du Capacity nicht kleiner als das aktuelle Size setze, sonst verschwinden schnell mal ein paar Daten.


Hmm, grade nchgesehn, uch in D7 wurde TMemoryStream schon optimiert, so daß nur in 8 KB-Schritten der Speicher vergrößert wird ... sind aber dennoch fast 2200 Größenänderungen und somit genut Anfagen an den Speichermanager.


Falls ich mich nicht verschrieben hab ... arbeitet in größeren Schritten
Delphi-Quellcode:
type
  TMyMemoryStream = class(TMemoryStream)
  protected
    function Realloc(var NewCapacity: LongInt): Pointer; override;
  public
    procedure SetCapacity(Value: LongInt);
  end;

function TMyMemoryStream.Realloc(var NewCapacity: LongInt): Pointer;
begin
  if NewCapacity > Capacity then begin
    if NewCapacity <= 2 shl 20 then // kleiner 2 MB
      inherited Realloc((NewCapacity + (1 shl 19 - 1)) and not (1 shl 19 - 1)); // 0.5 MB-Schritte
    else
      inherited Realloc((NewCapacity + (4 shl 20 - 1)) and not (4 shl 20 - 1)); // 4 MB-Schritte
  end else
    inherited;
end;

procedure TMyMemoryStream.SetCapacity(Value: LongInt);
begin
  if Value > Size then
    Capacity := Value;
end;

DelTurbo 15. Dez 2011 11:51

AW: VirtualTree und MemoryStream
 
Ich hatte auch eine idee. Ich "merke" mir die grösse des letzten speicherns. Dementsprechend gross setze ich den TMStream + eventuell 1MB falls er grösser wurde. Dann ist das prob nur beim aller ersten speichern da.

Aber deine sache werde ich auch mal probieren.

Danke dir. :thumb:

DelTurbo 15. Dez 2011 12:23

AW: VirtualTree und MemoryStream
 
Ich habs nun doch anders gemacht. Bekanntlich führen ja viele wege nach Rom. Ich hänge sowieso im OnSaveNode. Da merke ich mir beim "reinkommen" die größe von dem MS und beim verlassen schaue ich kurz nach ob er größer wurde. Wenn ja wird mit SetSite einfach ein MB zusätzlich gehohlt.

Es ist keinerlei Speed verlust zu merken.

EDIT: Ups, nicht schimpfen. Das sollte kein neues post werden. Mein fehler.....


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