Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#18

Re: Format-Funktion zu langsam

  Alt 27. Jan 2005, 19:04
Gut, du hast also gelernt das die Contenation von LongStrings sehr langsam sind und das es eventuell besser sein kann erstmal einfach die Tipps der erfahrenen Programmierer nicht sofort anzuzweifeln

In deinem Source betrifft das 6 Stellen:

Delphi-Quellcode:
V_line[Nr] := format('%s (:,:,%d) = [',[A[Nr],iz+1]) ;

                 V_line[Nr] := V_line[Nr] + FloatToStrF (C[Nr],ffFixed,7,4) + ' ' ; // langsam, heisst ung. 20 min.
                 //V_line[Nr] := V_line[Nr] + '0.0001 ' ; // schnell, par Sekündchen
                 if (iy = G.y-1) and (ix < G.x-1) then begin
                    V_line[Nr] := V_line[Nr] + '; ' ;
                 end ;
              end ;
           end ;
           V_line[Nr] := V_line[Nr] + '] ;' ;
Statt also mit V_line[nr] zu arbeiten änderst du sie in Aufrufe von Add() um. Im .Add() nimmst du das #13#10 raus und baust es manuell in deine Schleife rein.

.Add() selber kann nun zusätzlich beschleunigt werden indem man einen zb. 4Kb großen Buffer benutzt. Das beschleunigt dann das Dateisystem des Betriebsystemes das mit 1Kb-4Kb großen Schreibzugriffen am effizientesten ist.

Als nächstes würde man die Format() und FloatToStrF() funktionen umbauen. Diese würde dann NICHT mehr einen LongString als Resultat zurückgeben sondern in diesem großen Buffer[] direkt hinein-formatieren.

Somit wären alle LongString's und deren ständige Speicher- Alloziereungen/Deallozioerungen/Kopierungen entfernt.

Deine Funktion könnte abstrahiert dann so aussensehen:

Delphi-Quellcode:
procedure ExportMatrix(const Filename: String, ... blabla);
const
  Overhang = 256;
var
  Buffer: array[0..1024 * 4 -1 + Overhang] of Char; // 256 zeichen mehr für inplaced Format() etc. funktionen
  BufPos: Integer;
  Stream: TStream;

  procedure WriteBuffer;
  begin
    Stream.Write(Buffer, BufPos);
    BufPos := 0;
  end;

  procedure Put(Text: Char); overload;
  begin
    Buffer[BufPos] := Text;
    Inc(BufPos);
    if BufPos >= SizeOf(Buffer) - Overhang then WriteBuffer;
  end;
  
  procedure Put(const Text: PChar); overload;
  begin
    with Text^ <> #0 do
    begin
      Put(Text^);
      Inc(Text);
    end;
  end;

  procedure DoExport;
  var
    I,J: Integer;
 ..,blabla
  begin
 // hier Matrix exportieren
    for I := 0 to do
      for J := 0 to do
      begin
        Put(...);
        for K := 0 to do
        begin
          Put(...);
          Put(' ');
        end;
        Put(#13#10);
      end;
  end;

begin
  BufPos := 0;
  Stream := TFileStream.Create(FileName, fmCreate);
  try
    DoExport;
    WriteBuffer; // Rest des Buffers speichern
  finally
    Stream.Free;
  end;
end;
Der Buffer wird überdimensioniert um Overhang Zeichen damit nun die neuen Funktionen für Format(), FloatToStrF() in den Buffer direkt formatieren können.

Gruß Hagen
  Mit Zitat antworten Zitat