Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt? (https://www.delphipraxis.net/191345-tfilestream-write-langsam-wenn-man-nur-1-zeichen-schreibt.html)

a.def 4. Jan 2017 18:36

TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Ich schlage mich gerade mit einem TFileStream herum und merke, dass der doch recht langsam ist, wenn man
(Beispiel) 0 bis X-Tausend-Mal nur ein Zeichen schreibt.

Ich möchte gerne X-Mal ein Zeichen in eine Datei schreiben. X kann hier 0 bis mehrere Tausend Mal sein.
Ich dachte erst, ich verwende den Buffer. Aber bei einem Zeichen pro Aufruf ist das ja total sinnlos.

Hätte hier jemand eine bessere Idee?

Delphi-Quellcode:
aFileStream := TFileStream.Create('C:\test.txt', fmCreate or fmOpenWrite);

try
 for j := 0 to 14999 do
  begin
   sTmp := 'X';
   // aFileStream.WriteBuffer(Pointer(sTmp)^, Length(sTmp));
   aFileStream.Write(PChar(sTmp)^, Length(sTmp));
 end;
finally
 aFileStream.Free;
end;
Meine Idee wäre, jeweils XYZ Zeichen zu sammeln, in einen String schreiben und diesen dann mit dem FileStream schreiben. Aber ist das sinnvoll?

Daniel 4. Jan 2017 18:40

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Kilobytes oder auch eine Handvoll Megabytes kannst Du im Speicher vorbereiten und dann in einem Rutsch auf die Platte schreiben.
Im einfachsten Fall ein Array of Bytes btw. TArray<Byte> oder meinetwegen ein MemoryStream.
Alternativ gäbe es auch den "System.Classes.TBufferedFileStream", der genau dazu da ist, nacheinander viele kleine Dinge wegzuschreiben.

a.def 4. Jan 2017 18:56

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Danke für die Idee! Geht schon deutlich schneller.

Mein "Kot"
Delphi-Quellcode:
       iFileSizeToWrite := 15728640; // 15 MB
       aFileStream := TFileStream.Create('C:\test.txt', fmCreate or fmOpenWrite);

       try
        iBytesCounter := 0;
        repeat
         sTmp := '';
         for j := 1 to (1024 * 1024) do // 1 MB pro Durchgang
          begin
           sTmp := sTmp + 'X';
           Dec(iFileSizeToWrite);
           if iFileSizeToWrite = 0 then
            Break;
          end;

         aFileStream.Write(PChar(sTmp)^, Length(sTmp));
        until iFileSizeToWrite = 0;
       finally
        aFileStream.Free;
       end;
Ob das noch schneller ginge?

EWeiss 4. Jan 2017 18:57

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Zitat:

Mein "Kot"
OT:

Macht der irgendwo hin?
Zumindest sehe ich keine Fäkalien.

gruss

Daniel 4. Jan 2017 19:01

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Zitat:

Zitat von a.def (Beitrag 1358096)
Ob das noch schneller ginge?

Bist Du sicher, dass ein String das rechte Werkzeug zur Datenhaltung ist? Du baust den ja Zeichen für Zeichen auf. Das arme Ding wird im Speicher kreuz und quer kopiert. Wenn es unbedingt ein String bleiben soll, dann setze dessen Länge einmalig am Anfang und setze die einzelnen Zeichen dann über deren Index (ala s[1] := 'X'; ).

a.def 4. Jan 2017 19:07

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Zitat:

Zitat von EWeiss (Beitrag 1358097)
Zitat:

Mein "Kot"
OT:

Macht der irgendwo hin?
Zumindest sehe ich keine Fäkalien.

gruss

Ich dachte ich nenne es "Kot", da es definitiv keiner guter Code ist :thumb:


Zitat:

Zitat von Daniel (Beitrag 1358098)
Zitat:

Zitat von a.def (Beitrag 1358096)
Ob das noch schneller ginge?

Bist Du sicher, dass ein String das rechte Werkzeug zur Datenhaltung ist? Du baust den ja Zeichen für Zeichen auf. Das arme Ding wird im Speicher kreuz und quer kopiert. Wenn es unbedingt ein String bleiben soll, dann setze dessen Länge einmalig am Anfang und setze die einzelnen Zeichen dann über deren Index (ala s[1] := 'X'; ).

Ok ein kleiner Test. Mit meinem... Code... da oben: 512MB in ~7,3 Sekunden. Mit einem array of string ~17 Sekunden.
Mit sTmp: string; SetLength(sTmp, XYZ); sTmp[1] := 'X'; bekomme ich leider eine AV.

EWeiss 4. Jan 2017 19:09

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Zitat:

Ich dachte ich nenne es "Kot", da es definitiv keiner guter Code ist
Tja dann ist es berechtigt ;)
War auch nur ein joke :)

gruss

a.def 4. Jan 2017 19:21

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Ich habe gerade ein Programm getestet, dass mehrere GB in wenigen Sekunden auf die Platte schreibt :pale:

Daniel 4. Jan 2017 19:25

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Wo genau willst Du hin?
Du möchtest offenbar ein bestimmtes Byte vielfach in eine Datei schreiben?
Über welche Größenordnung an Dateigröße reden wir konkret? Bislang war in Deinem ersten Beitrag von Kilobytes die Rede.
Über welche Anforderungen an das Zeitverhalten reden wir? Bei "mehreren GB pro Sekunde" reden wir langsam auch von Hardwarefragen.

a.def 4. Jan 2017 19:28

AW: TFileStream.Write langsam, wenn man nur 1 Zeichen schreibt?
 
Stimmt das sollte ich mal klären.
Es kann um Dateigrößen von Bytes bis GBytes gehen. Je nachdem was man angibt.
Das sollen eigentlich nur dummy-Dateien werden. Den Inhalt kann man ebenfalls bestimmen. Entweder ein zufälliges Zeichen oder ein definiertes Zeichen.

Ich bin schon so weit, dass alles korrekt arbeitet. Nur 7 Sekunden für 512 MB auf eine SSD ist ein wenig happig :pale:

P.S.: das Tool, das mehrere GB pro Sekunde schreibt, das war auf meinem PC :P


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 Uhr.
Seite 1 von 4  1 23     Letzte »    

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