![]() |
Geschwindigkeitsunterschied TFilestream TMemorystream
Tag zusammen
folgender Code lest alle Dateien die sich in der übergebenen Stringlist befinden in einen Stream der noch anschliessend komprimiert wird.
Delphi-Quellcode:
Ich wollte eigentlich das ganze ohne zwischendateien lösen das funktionierte auch wunderbar mit memorystream mit kleinen dateien. Dann testete ich das verfahren allerdings mit grossen files
procedure TClDateiTransfer.ErzStreamObjUbertr(aObjList: TStringList; StatusBar:TStatusBar);
var aFs:TFileStream; aTempFs:TFileStream oder TMemorystream; aDateiGr:Int64; aDatName:String; i:Integer; begin aTempFs:=TFileStream.Create('temp.str',fmCreate); //TMemoryStream.Create; try for i:=0 to aObjList.Count-1 do begin aFs:=TFileStream.Create(aObjList.Strings[i], fmOpenRead); try aDateiGr:=aFs.Size; aTempFs.Write(aDateiGr, sizeof(aDateiGr)); aDatName:=ExtractFileName(aObjList.Strings[i]); StringStrSpeichn(aDatName, aTempFs); StatusBar.Panels[0].Text:='... bearbeite '+aDatName; Application.ProcessMessages; sleep(100); aTempFs.CopyFrom(aFs, aFs.Size); finally aFs.Free; end; end; StatusBar.Panels[0].Text:='... Dateien werden komprimiert'; Application.ProcessMessages; aTempFs.Position:=0; ZCompressStream(aTempFs, poStreamUbertr, zcFastest); StatusBar.Panels[0].Text:='... starte Übertragung'; Application.ProcessMessages; finally aTempFs.Free; DeleteFile('temp.str'); end; end; 3 dateien (2 mit 38 Mb und 1 mit 26 Mb) also zusammen ca 100 Mb und stellte etwas sehr merkwürdiges fest: der Stream der zu komprimieren ist wird in der variable aTempFs gespeichert entweder Klasse TFilestream oder TMemorystream Mit TMemoryStream brauchte der code bis vor der komprimierung über 3 Min :wall: :wall: Mit TFilestream ca 15 sec :thumb: Kann mir das bitte jemand erklären warum normal müsste doch Ram schneller als Platte sein :?: Gibts es eine andere Möglichkeit um MemoryStream schneller zu machen :?: |
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
Nicht wenn der Adressraum deiner Anwendung stark fragemnetiert ist, denn dann bekommt der Memorymanager ziemliche Problem Speicherblöcke zur Verfügung zu stellen, die groß genug sind. Jedenfalls würde ich mir das so erklären.
|
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
das heist in meinem fall sollte ich mit filestream arbeiten und die temp datei nachher löschen :?:
|
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
was ist so schlimm daran? du kannst ja überprüfen ob du genügend platz für die temp hast und wenn ja den filestream nehmen und wenn nein den memorystream.
|
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
es ist nichts schlimm dran mich hat es nur interessiert ob man den code für den memorystream ändern und damit schneller machen kann oder ob für solche aufgaben generell ein filestream zu empfehlen ist.
|
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
Wenn Du folgenden Code vor der For-Schleife einfügst, dauert auch nur 3 Sekunden, weil der Speicher in einem Mal am Stück reserviert wird (evtl. musst Du noch etwas für die Dateinamen hinzufügen, weil ich nicht weiss, was Du in StringStrSpeichn tust):
Delphi-Quellcode:
aDateiGr := 0;
for i:=0 to aObjList.Count-1 do begin aFs:=TFileStream.Create(aObjList.Strings[i], fmOpenRead); try aDateiGr:= aDateiGr+aFs.Size+length(aObjList.Strings[i])+1; finally aFs.Free; end; end; // Speicher wird nur einmal reserviert aTempFs.SetSize(aDateiGr); // Hier geht's mit Deinem Code weiter for i:=0 to aObjList.Count-1 do |
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
hallo union
hier erstmal die funktion StringStrSpeichn
Delphi-Quellcode:
in der Stringlist stehen 1-x Vollständige Dateinamen (kompletter Pfad + Dateiname + ext)
procedure TClDateiTransfer.StringStrSpeichn(ZeichenFolge: String;
ZielStr: TStream); var i: Integer; begin i := Length(ZeichenFolge); ZielStr.Write(i, sizeof(i)); ZielStr.Write(ZeichenFolge[1], i); end; in den stream wird dann je item in der stringlist folgendes geschrieben: Dateigrösse / Dateiname+ext (Bsp. KU_Mapos.Dat) / die eigentliche Datei dein vorschlag hört sich sehr gut an. was gehört hier hin
Delphi-Quellcode:
oder :?:
try
aDateiGr:= aDateiGr+aFs.Size+length(aObjList.Strings[i])+1; //warum +1 ??? //imho aDateiGr:=sizeof(aDateiGr)+???+aFs.Size //Speicher für Int64 + Speicher für String (Dateiname+ext)+ Speicher für Datei binär finally aFs.Free; end; |
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
Danke union war wiedermal hammertip
Delphi-Quellcode:
:hello: :hello: :hello:
aDateiGr := 0;
for i:=0 to aObjList.Count-1 do begin aFs:=TFileStream.Create(aObjList.Strings[i], fmOpenRead); try aDatName:=ExtractFileName(aObjList.Strings[i]); //aDateiGr:= aDateiGr+aFs.Size+length(aObjList.Strings[i])+1; aDateiGr:=aDateiGr + sizeof(aDateiGr)+sizeof(i)+sizeof(aDatName)+aFs.Size; finally aFs.Free; end; end; aTempFs.SetSize(aDateiGr); StatusBar.Panels[0].Text:='... reserviert '+IntToStr(aDateiGr); die selben 3 dateien brauchen jetzt mit dem Memorystream unter 4 sekunden bis die komprimierung startet |
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
Delphi-Quellcode:
Du darfst dort nicht mit SizeOf(aDatName) arbeiten, das gibt nämlich ein Byte mehr zurück.
aDateiGr:=aDateiGr + sizeof(aDateiGr)+sizeof(i)+sizeof(aDatName)+aFs.Size;
Delphi-Quellcode:
Showmessage(Format('Length(''ABC'') => %d'#13'SizeOf(''ABC'') => %d', [Length('ABC'), Sizeof('ABC')]));
Zitat:
|
Re: Geschwindigkeitsunterschied TFilestream TMemorystream
Also SizeOf(String) liefert IMMER 4 zurück!
Das Liegt dadran, dass im String nur eine Zeiger auf den Speicher gespeichert wird. Dieser zeiger ist dabei halt 4 bytes gross. Also bei Strings NIE SizeOf nutzen. Immer Lenght benutzen. Denn ein SizeOf(string)-1 würde dementsprechend immer 3 zurückliefern, egal wielang der String ist. ( Späte Antwort... war auf der Suche nach etwas, was komprimieren kann... und dabei ned aufs Datum geschaut ) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:44 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