Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi IniFile zu langsam (https://www.delphipraxis.net/56821-inifile-zu-langsam.html)

Neutral General 11. Nov 2005 19:21


IniFile zu langsam
 
Hi,

Delphi-Quellcode:
procedure TEditWorld.New(Width:Integer; Height:Integer);
var x,y,i : Integer;
begin
 i:= 0;
 World.Width := Width;
 World.Height:= Height;
 if FLevel <> nil then FLevel.Free;
 FLevel := TIniFile.Create(ExtractFilePath(Application.Exename) + 'Default.ini'); //Default.ini erstellen
 FLevel.WriteInteger('Count','Count',Width*Height);
 for y:= 0 to Height-1 do begin // reinschreiben
  for x:= 0 to Width-1 do begin
    inc(i);
    FLevel.WriteString('Tex' + IntToStr(i),'Tex','Wasser');
    FLevel.WriteInteger('Tex' + IntToStr(i),'x',x);
    FLevel.WriteInteger('Tex' + IntToStr(i),'y',y);
  end;
 end;
 FLevel.UpdateFile;
 LoadFromFile('Default.ini'); //nicht sooo wichtig
end;
So. Und je nachdem wie groß die Welt sein soll können das schonmal 2500 Einträge sein... Und das ist viel und vorallem dauert das ewig das alles in eine Datei zu schreiben..
Geht das nicht irgendwie schneller ?

A-M-X 11. Nov 2005 19:23

Re: IniFile zu langsam
 
ich würds so machen: nach dem schließen bzw dem drücken auf Speichern (o.Ä.) ein anderes programm dafür benutzen , das das im (totalen) hintergrund macht.

mfg
a-m-x :hi:

Khabarakh 11. Nov 2005 19:29

Re: IniFile zu langsam
 
Zitat:

Zitat von A-M-X
ich würds so machen: nach dem schließen bzw dem drücken auf Speichern (o.Ä.) ein anderes programm dafür benutzen , das das im (totalen) hintergrund macht.

mfg
a-m-x :hi:

Ein zweites Programm? Wenn dann eher einen zweiten Thread, aber damit umfährt man auch nur das Problem, dass Ini-Files eigentlich nur zum Speichern von Einstellungen gedacht sind. Ich würde einen Filestream oder eine Textdatei per StringList benutzen. Das sollte um einiges schneller sein.

Neutral General 11. Nov 2005 19:31

Re: IniFile zu langsam
 
Zitat:

Zitat von Khabarakh
Zitat:

Zitat von A-M-X
ich würds so machen: nach dem schließen bzw dem drücken auf Speichern (o.Ä.) ein anderes programm dafür benutzen , das das im (totalen) hintergrund macht.

mfg
a-m-x :hi:

Ein zweites Programm? Wenn dann eher einen zweiten Thread, aber damit umfährt man auch nur das Problem, dass Ini-Files eigentlich nur zum Speichern von Einstellungen gedacht sind. Ich würde einen Filestream oder eine Textdatei per StringList benutzen. Das sollte um einiges schneller sein.

Und wie würde das mit dem Filestream z.B in der Praxis aussehen.. Ich wüsste nicht wie das funktionieren soll :mrgreen:
Und wie man die Informationen da wieder raus kriegen will...

A-M-X 11. Nov 2005 19:31

Re: IniFile zu langsam
 
oder die simple methode : den benutzer warten lassen :D

Luckie 11. Nov 2005 19:31

Re: IniFile zu langsam
 
Ini-Dateien sind für diese Menge an Daten auch nicht ausgelegt!!! Speicher es lieber in typisierten Dateien oder ähnlichen.

Neutral General 11. Nov 2005 19:34

Re: IniFile zu langsam
 
Zitat:

Zitat von A-M-X
oder die simple methode : den benutzer warten lassen :D

:roll:
Zitat:

Zitat von Luckie
Ini-Dateien sind für diese Menge an Daten auch nicht ausgelegt!!! Speicher es lieber in typisierten Dateien oder ähnlichen.

Ja das ist mir auch klar das Ini-Dateien dafür eigentlich nicht gedacht sind.. :mrgreen:
Und wie würde das mit den typisierten Dateien denn aussehen etwa ?

Die Muhkuh 11. Nov 2005 19:41

Re: IniFile zu langsam
 
Hi,

versuch es mal mit TBigIniFile.

Neutral General 11. Nov 2005 19:45

Re: IniFile zu langsam
 
Zitat:

Zitat von Spider
Hi,

versuch es mal mit TBigIniFile.

Das ist die Lösung!! Das ist genial.. Das geht uuuuuuuunendlich mal schneller!! Mit der normalen iniFile brauche ich für 2500 Einträge fast ne halbe Minute und mit dem Wunderding nichtmal ne Sekunde! :firejump: :hello: :)

Wer irgendwann mal ein ähnliches Problem haben sollte -> TBIGINIFILE !! :dp:

alzaimar 11. Nov 2005 20:16

Re: IniFile zu langsam
 
Tschuldige mal bitte, aber was ist an 2500 Einträgen in einer Sekunde bitteschön so toll? Das hat mein 286er vor 150 Jahren auch schon geschafft. Mehr als 100ms würde ich bei 2500 Einträgen nicht akzeptieren...

r4id3n 11. Nov 2005 20:30

Re: IniFile zu langsam
 
@alzaimar:
Wenn Ini-Dateien aber über 42 kb groß werden, werden diese unendlich langsam! Das ist ein bekanntes Problem!
Das Zauberwort heißt wirklich nur TBigIni....

s.h.a.r.k 11. Nov 2005 20:42

Re: IniFile zu langsam
 
Also falls es euch was hilft: Ich habe da mal so ein Testprogramm geschrieben und mit GetTickCount die Zeit gemessen wie lange eine Sicherung von Daten dauert. Die Rahmenbedingungen waren:

1. Erstellungen von 1000 Dateien
2. Inhalt: jeweils 4 Strings, 4 Integer- und 4 Boolean-Werte
3. Gemessen wurde mit GetTickCount


Die dabei benötigten Zeiten waren:

indizierte Dateien (Type of...): ~ 3000ms
INI-Dateien (IniFile.WriteString): ~ 3000ms
"Normale" Dateien(writeln(bla...)): 150ms

Ich habe damit also nur die Schreibmehtode getestet, nicht die Lesemethode!

bigg 11. Nov 2005 21:58

Re: IniFile zu langsam
 
@s.h.a.r.k.

1. Kannst du getrost streichen, denn es bringt nichts 1000 Dateien anzulegen und diese mit minimalen
Inhalt zu füttern. Wie groß sind die Dateien? Sicherlich nicht größer als 512 Byte, oder?

Wenn du wesentlich mehr Einträge und zudem nur eine Datei anlegst, erhälst du ein genaueres Ergebnis.

Das musste mal gesagt werden :mrgreen:

3_of_8 11. Nov 2005 23:10

Re: IniFile zu langsam
 
Sind indizierte Dateien typisierte Dateien?

fkerber 11. Nov 2005 23:38

Re: IniFile zu langsam
 
HI!

Wenn man nach dem (type of) in Klammer geht wohl schon ;)


Ciao Frederic

alzaimar 12. Nov 2005 09:05

Re: IniFile zu langsam
 
Zitat:

Zitat von r4id3n
@alzaimar:
Wenn Ini-Dateien aber über 42 kb groß werden, werden diese unendlich langsam! Das ist ein bekanntes Problem!
Das Zauberwort heißt wirklich nur TBigIni....

[edit]Das ist kein Problem, sondern in der Tatsache begründet, das TIniFile alle Änderungen per definitionem sofort auf die Platte schreibt. "It's not a bug, it's a feature".[/edit].
Und das Zauberwort heisst sicherlich nicht TBigIni, sondern z.B. 'TFileStream' oder Ähnliches.
  • TIniFile = Richtig langsam
    TBigIniFile = Na ja
    TFileStream = Schnell
Ich hab mal ein Testprogramm (5000 Sections mit je 10 Werten) geschrieben. Hier meine Ergebnisse:
  • BigIni File : 14001 ms
    FastIniFile : 780 ms
    Filestream : 641 ms
TMemIniFile und TIniFile scheiden aus, denn sie sind immer noch nicht fertig ;-).

FastIniFile hab ich eben selbst geschrieben (es basiert auf einer TStringdictionary). Filestream schreibt die Werte als 'Section-Name=Value' in die Datei.

Natürlich ist TBigIni ausreichend, aber was ich meinte, ist das es schon befremdlich ist, sich bei 3GHZ-Rechnern über eine Performance von 1000mszu freuen, um lächerliche 10000 Strings abzuspeichern. Und wie man oben sieht, ist TBigIniFile dann auch irgendwann mal Schrott.

Jelly 12. Nov 2005 09:11

Re: IniFile zu langsam
 
Zitat:

Zitat von alzaimar
Und wie man oben sieht, ist TBigIniFile dann auch irgendwann mal Schrott.

Inifiles sind für solche Datenmengen ja auch einfach nicht gedacht. Und noch zur Ergänzung: eine normale INI Datei darf mit TIniFile nicht grösser als 64kB haben, was bislang noch nicht erwähnt wurde.

neolithos 12. Nov 2005 09:17

Re: IniFile zu langsam
 
Ich würde ja empfehlen solche speziellen Daten binär in eine Datei abzulegen. Sollte das schnellste sein und auch wieder gut auslesbar sein. (Außerdem spart man Platz)

alzaimar 12. Nov 2005 09:29

Re: IniFile zu langsam
 
Hab ich (siehe 'Filestream'). Das ist so gut wie binär, denn irgendwie muss man ja auch die Schlüsselinformation (Section, Name) ablegen. Der zusätzliche Overhead, um die Sachen auch schnell wiederzufinden (TStringDictionary) fällt aber sowieso nicht ins Gewicht.

Man muss dazusagen, das TBigIni ganz nett ist, aber (so wie es der Autor schreibt) nicht optimal. Immerhin schreibt es nicht jede Änderung direkt auf die Platte, wie das TIniFile (gottseidank) tut. Aber man sieht eben auch, das die von Borland bereitgestellten Klassen alles Andere als optimal implementiert sind. Selbst die THashedStringList, die beim TMemIniFile zum Einsatz kommt (wenn ich nicht irre), ist nicht berauschend.

TBigIni benutzt einen einfachen Trick, um schnell zu werden: Es geht zurecht von der Annahme aus, das man die [Section,Name] Tupel nicht wahllos verwendet, sonder i.A. alle Werte einer Section hintereinander schreibt, es entfällt dann die Suche nach den Sections. So genau hab ich mir den jetzt aber nicht angeschaut.

Grundsätzlich ist es aber wirklich so, das man Ini-Files nicht für Tausende von Einstellungen nehmen sollte. Ich würde das dann auch einfach in eine Collection packen und die dann wegstreamen, schon der Ästhetik wegen.

Neutral General 12. Nov 2005 11:05

Re: IniFile zu langsam
 
Guut. Also eigentlich reicht mir die TBigIniFile aus aber:

Ich würde gerne mal die TFastIniFile von r4id3n testen und ich wäre euch dankbar wenn jemand mir mal einen Ansatz mit ein bisschen Quellcode gibt, wie ich das mit einem Filestream machen kann :)

alzaimar 12. Nov 2005 11:16

Re: IniFile zu langsam
 
Zitat:

Zitat von Neutral General
...Ich würde gerne mal die TFastIniFile von r4id3n ...

Wer hats erfunden? :mrgreen:
Kriegste später, ich bin grad unterwegs.

neolithos 14. Nov 2005 00:31

Re: IniFile zu langsam
 
Delphi-Quellcode:
procedure TEditWorld.New(Width:Integer; Height:Integer);
var x, y, iTmp : Integer;
begin
  World.Width := Width;
  World.Height:= Height;
  if FLevel <> nil then
     FLevel.Free;

  FLevel := TFileStream.Create(ExtractFilePath(Application.Exename) + 'Default.dat', fmCreate);
  iTmp := Width * Height;
  FLevel.Write(iTmp, SizeOf(iTmp));
  for y := 0 to Height - 1 do
     begin // reinschreiben
       for x := 0 to Width - 1 do
         begin
           // FLevel.WriteString('Tex' + IntToStr(i),'Tex','Wasser'); das sollte man
           // eventuell via Enum lösen, damit auch ein integer geschrieben werden kann,
           // vorteil: partielles laden einfach möglich
           // muss es unbedingt ein String sein, gib bescheid
          FLevel.Write(x, SizeOf(x));
          FLevel.Write(y, SizeOf(x));
        end;
     end;
//  FLevel.Free;
end;
Ich würde das ja eher so machen:

Delphi-Quellcode:
type
  TLevelHeader = record
    dwSg : Cardinal;
    iHeight,
    iWidth : Integer:
  end;

  TAreaType = (atWater, atLand);

procedure TEditWorld.New(Width:Integer; Height:Integer);
var x, y : Integer;
    fTmp : TAreaType;
    rHead : TLevelHeader;
begin
  World.Width := Width;
  World.Height:= Height;
  if FLevel <> nil then
     FLevel.Free;

  FLevel := TFileStream.Create(ExtractFilePath(Application.Exename) + 'Default.dat', fmCreate);
  rHead.dwSg := 1234567;
  rHead.iHeight := Height;
  rHead.iWidth := Width;
  iTmp := Width * Height;
  FLevel.Write(iTmp, SizeOf(iTmp));
  for y := 0 to Height - 1 do
     for x := 0 to Width - 1 do
       begin
         fTmp := atWater;
         FLevel.Write(fTmp, 1);
       end;
end;

Neutral General 14. Nov 2005 11:43

Re: IniFile zu langsam
 
Ja hab das Problem jetzt eingermaßen mit Filestreams in den Griff bekommen.
Siehe meinen RPG-Editor Thread

Danke nochmal an alle :)


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