AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TStrings ist *unglaublich* langsam

Ein Thema von WordsBG · begonnen am 18. Jul 2007 · letzter Beitrag vom 18. Jul 2007
Antwort Antwort
Benutzerbild von WordsBG
WordsBG

Registriert seit: 17. Sep 2005
63 Beiträge
 
Delphi 7 Professional
 
#1

TStrings ist *unglaublich* langsam

  Alt 18. Jul 2007, 00:10
Hallo!
Ich habe ein Problem bei einem Programm an dem ich gerade arbeite. Sicher habt ihr schon einmal von GTA (Grand Theft Auto) gehört und wenn ihr dort Erfahrung habt wisst ihr vielleicht, dass es rund um diese Spieleserie eine große internationale Fangemeinde gibt, die sich im speziellen mit dem Modden des Spiels beschäftigt. Da mich neue Autos und ähnliches weniger interessieren, bin ich meistens bei den Scriptern unterwegs. Die GTA-Engine nutzt eine binär-kompilierte Datei (main.scm). Diese hat einen recht simplen Aufbau, welcher sich hier nachlesen lässt: Klick. Nun gibt es für das (noch) neuste GTA "San Andreas" im Grunde nur zwei Editoren zum dekompilieren/neu kompilieren dieser Datei, von denen einer nicht mehr gewartet wird und unter massiven Fehlern leidet und ein zweiter (aus Russland), welcher "nur" Freeware ist und dem (meiner Meinung nach) noch einige Features fehlen um perfekt zu sein. Jedenfalls habe ich mir überlegt meine Delphi Erfahrung (müssten nun 3 Jahre sein) zu nutzen um einen weiteren Open-Source Editor zu basteln. Bisher allerdings hatte ich noch keine größere Erfahrung mit binären Dateien, doch TFileStream machte im gepufferten Zustand kaum Probleme, ganz im Gegensatz zu meinem alten Freund TStrings der scheinbar mit meiner massiven Anzahl an Updates kaum klarkommt.
Die Standard main.scm ist ca. 3mb groß, getestet habe ich alles an einer 1kb main.scm und alles lief prima, doch schon bei rund 70kb macht mir TString massive Probleme. Wenn ich alle Ausgabe-Befehle auskommentiere läuft es innerhalb von zwei Sekunden durch, genau wie es sollte, mit TStrings wird es mit steigender kb Zahl immer langsamer (ersichtlich wenn man sich die abgearbeiteten kb ausgeben lässt), so dauert es von 2 auf 3 kb einige Sekunden und von 61 auf 62 ewige Jahre. Deshalb, nach dieser ewigen Einleitung, meine Frage was ich dagegen tun könnte.

Hier der Quellcode der entsprechenden Funktion (muss evt. noch an einigen Stellen geändert werden ).


Delphi-Quellcode:
procedure TfrmMain.btnOpenClick(Sender: TObject);
var
  FS: TJclBufferedStream;
  I, J, K: Integer;
  Ch : Char;
  EndOfHeader: Boolean;
  High, Low: String;
  IsHigh: Boolean;
  Param: Integer;
  ParamTyp, ParamSCMStr: String;
  ini: TINIFile;
begin
  if NOT OpenDialog.Execute then
    Exit;
  Code.Lines.Clear;
  EndOfHeader := False;
  IsHigh := False;
  try
    Code.Lines.BeginUpdate;
    FS := TJclBufferedStream.Create(TFileStream.Create(OpenDialog.FileName, fmOpenRead),True);
    ini := TINIFile.Create(ExtractFilePath(Application.ExeName)+'SASCM.ini');
    I := 0;
    While I < FS.Size do
    begin
      Caption := FloatToStr(I DIV 1024);
      Application.ProcessMessages;
      FS.Read(Ch, SizeOf(Ch));

      if IntToHex(Ord(Ch),2) = 'A4then
        EndOfHeader := True;
      if NOT EndOfHeader then
        Code.Lines.Text := Code.Lines.Text + IntToHex(Ord(Ch),2)
      else
      begin
        If IsHigh then
          High := IntToHex(Ord(Ch),2)
        else
          Low := IntToHex(Ord(Ch),2);
        if isHigh then
        begin
          ParamSCMStr := ini.ReadString('main',LowerCase(High+Low),'0,');
          ParamSCMStr := Copy(ParamSCMStr, Pos(',',ParamSCMStr)+1, Length(ParamSCMStr));
          Code.Lines.Add(GetOP(High, Low, ParamSCMStr));
          ParamSCMStr := ini.ReadString('main',LowerCase(High+Low),'0,');
          ParamSCMStr := Copy(ParamSCMStr,1,Pos(',',ParamSCMStr)-1);
          for K := 1 to StrToInt(ParamSCMStr) do
          begin
            Application.ProcessMessages;
            FS.Read(Ch, SizeOf(Ch));
            I := I + 1;
            Param := Ord(Ch);
            case Param of
              01: begin Param := 4; ParamTyp := 'INT32'; end;
              02: begin Param := 2; ParamTyp := 'GVAR'; end;
              03: begin Param := 2; ParamTyp := 'LVAR'; end;
              04: begin Param := 1; ParamTyp := 'INT8'; end;
              05: begin Param := 2; ParamTyp := 'INT16'; end;
              06: begin Param := 4; ParamTyp := 'FLOAT32'; end;
              07: begin Param := 6; ParamTyp := 'GARRAY'; end;
              08: begin Param := 6; ParamTyp := 'LARRAY'; end;
              09: begin Param := 8; ParamTyp := 'STR8'; end;
              10: begin Param := 2; ParamTyp := 'GSTR8'; end;
              11: begin Param := 2; ParamTyp := 'LSTR8'; end;
              12: begin Param := 6; ParamTyp := 'GSTRA8'; end;
              13: begin Param := 6; ParamTyp := 'LSTRA8'; end;
              14: begin
                    FS.Read(Ch, SizeOf(Ch));
                    I := I + 1;
                    Param := Ord(Ch);
                    ParamTyp := 'USTR';
                  end;
              15: begin Param := 16; ParamTyp := 'STR16'; end;
              16: begin Param := 2; ParamTyp := 'GVSTR'; end;
              17: begin Param := 2; ParamTyp := 'LVSTR'; end;
              18: begin Param := 6; ParamTyp := 'GVSTRA'; end;
              19: begin Param := 6; ParamTyp := 'LVSTRA'; end;
              else
              begin
                Param := 0;
                ParamTyp := '';
              end;
            end;
            if ParamTyp <> 'then
            begin
              Code.Lines.Text := Code.Lines.Text + ParamTyp + ' ';
              for j := Param downto 1 do
              begin
                FS.Read(Ch, SizeOf(Ch));
                I := I + 1;
                Code.Lines.Text := Code.Lines.Text + IntToHex(Ord(Ch),2)+' ';
              end;
            end;
          end;
        end;
        IsHigh := NOT IsHigh;
      end;
      I := I + 1;
    end;
  finally
    FS.Free;
    ini.Free;
    Code.Lines.EndUpdate;
  end;
end;
Angehängt mal das komplette Projekt, falls jemand eine Idee hat (beide scms [70kb + mini 1kb] sind mal mit drin, zum testen [Beide übrigens inoffiziell und somit nicht vom Copyright des Spieleherstellers betroffen]). Oh und ja, mein Programm entziffert den Header (noch) nicht.
Angehängte Dateien
Dateityp: zip gta_sa_-_mission_coder_115.zip (28,7 KB, 5x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: TStrings ist *unglaublich* langsam

  Alt 18. Jul 2007, 00:22
Das ist eine Bremse:
Code.Lines.Text := Code.Lines.Text + ParamTyp + ' '; Jedes mal, wenn auf die Texteigenschaft zugegriffen wird, wird alles ausgelesen. Warum nimmst du nicht die Methode Add von Lines?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von WordsBG
WordsBG

Registriert seit: 17. Sep 2005
63 Beiträge
 
Delphi 7 Professional
 
#3

Re: TStrings ist *unglaublich* langsam

  Alt 18. Jul 2007, 00:25
Zitat von Luckie:
Das ist eine Bremse:
Code.Lines.Text := Code.Lines.Text + ParamTyp + ' '; Jedes mal, wenn auf die Texteigenschaft zugegriffen wird, wird alles ausgelesen. Warum nimmst du nicht die Methode Add von Lines?
In dem Fall gäbe es eine neue Zeile und in meinem Test war Code.Lines[Code.Lines.Count-1] nicht viel besser, aber ich werde es mal mit einem Temp-String und TStrings.Add Versuchen.

edit: Ok, vielen Dank. Dein Tipp hat hier wirklich geholfen und den Prozess um das 1000-fache beschleunigt.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:37 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