Autor Beitrag
Heiko
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Mi 21.09.05 16:25 
Der Titel sagt ja eigentlich schon alles ;): Wie kann man am schnellsten den String bis zum dem nächsten Zeilenumbruch auslesen? Bisher mache ich es immer so, dass ich jedes Zeichen einzelnd auf den Zeilenumbruch überprüfe. Geht das auch effektiver?
Grishnak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mi 21.09.05 16:36 
String oder Stream?

bei String: Pos()

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Mi 21.09.05 16:40 
Ne, bei einem Stream. Und mit Pos meinste, das ich nach #13#10 suchen soll ;).
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 21.09.05 17:30 
Du kannst ein Stream Buffering verwenden:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
var
    Len: Integer;
    Remaining: Integer;
    C: PChar;
    Data: String;
begin
    Len := 0;
    Remaining := MS.Size - MS.Position;
    
    C := PChar(Integer(MS.Memory) + MS.Position);
    While (Len < Remaining) and not (C^ in [#13#10]) Do 
    Begin
        Inc(C);
        Inc(Len);
    end;

    SetLength(Data, Len);
    MS.ReadBuffer(Data[1], Len);

    If not IsBadReadPtr(C, 1AND (C^ = #13Then
    Begin
        Inc(C^);
        If not IsBadReadPtr(C, 1AND (C^ = #10Then
            MS.Seek(2, soCurrent)
        Else
            MS.Seek(1, soCurrent);
    end
    else
        MS.Seek(1, soCurrent);
end;


Ungetestet.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 21.09.05 20:11 
Hallo,

einfach in eine Stringliste packen.
Das ist so verblueffend schnell.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
StrL :Tstringlist;

StrL.create;
Strl.LoadFromStream(memstream);
...


Gruss Horst

Moderiert von user profile iconKlabautermann: Code- durch Delphi-Tags ersetzt
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Mi 21.09.05 20:22 
Ich glaube nicht, dass es wirklich Performancevorteile bietet (ist zu einfach ;) ), da StringListen eigentlich nicht so für gute Performance bekannt ist ;). Trotzdem thx für die Idee.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 21.09.05 23:22 
Hallo,

ich habe mal code-Schnipseln aus dennishomepage.gugs-.../FastCodeProject.htm wie zum Beispiel PosEX bzw.PosEy (ein char suchen) gut verwenden koennen.
CharPosEY:
fuer Athlon und P4 das schnellste:
Aus dennishomepage.gugs-...dk/CharPosEYBV12.zip
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
function CharPosEY_JOH_IA32_2_d(const SearchCharacter : Char;
                              const SourceString : AnsiString;
                              Occurrence : Integer = 1;
                              StartPos   : Integer = 1): Integer;
asm
  push   ebx
  push   edi
  push   edx                   {@SourceString}
  test   edx, edx
  jz     @@NotFound            {Exit if SourceString = ''}
  sub    ecx, 1                {Occurrence - 1}
  jl     @@NotFound            {Exit if Occurence < 1}
  cmp    StartPos, 1
  jl     @@NotFound            {Exit if StartPos < 1}
  mov    ebx, [edx-4]          {Length(SourceString)}
  lea    ebx, [edx+ebx-1]      {Last Character Position}
  mov    edx, StartPos
  add    edx, [esp]            {@SourceString}
  sub    edx, 1                {@SourceString + StartPos - 1}
  jmp    @@CheckFinish
@@Loop:
  cmp    al, [edx]
  jne    @@Done1
  sub    ecx, 1                {Match}
  jc     @@SetResult1
@@Done1:
  cmp    al, [edx+1]
  jne    @@Done2
  sub    ecx, 1                {Match}
  jnc    @@Done2
  cmp    edx, ebx
  jge    @@NotFound
  jmp    @@SetResult2
@@Done2:
  cmp    al, [edx+2]
  jne    @@Done3
  sub    ecx, 1                {Match}
  jnc    @@Done3
  cmp    edx, ebx
  jg     @@NotFound
  jmp    @@SetResult3
@@Done3:
  cmp    al, [edx+3]
  jne    @@Done4
  sub    ecx, 1                {Match}
  jnc    @@Done4
  add    edx, 3
  cmp    edx, ebx
  jle    @@SetResult1
@@Done4:
  add    edx, 4
@@CheckFinish:
  lea    edi, [edx+ecx]
  cmp    edi, ebx
  jle    @@Loop
@@NotFound:
  xor    eax, eax
  pop    edx
  jmp    @@Exit;
@@SetResult3:
  add    edx, 1
@@SetResult2:
  add    edx, 1
@@SetResult1:
  pop    ecx                   {@SourceString}
  neg    ecx                     
  lea    eax, [edx+ecx+1]
@@Exit:
  pop    edi
  pop    ebx
end;



Vielleicht ist das genau was Du suchst.

Gruss Horst
P.S.:
Hast Du mal Stringlisten probiert?

Moderiert von user profile iconMotzi: Code- durch Delphi-Tags ersetzt
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Di 27.09.05 16:44 
Hallo,

ich habe es jetzt mal getestest:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
procedure TForm1.Button1Click(Sender: TObject);
var
  T0,T1,T2,T3,T4,Tf: int64;
  i,StartPos,EndPos : Cardinal;
  l : integer;
  pCr : pchar;
begin
  ms:= TMemoryStream.Create;
  ms.Clear;
  If FileExists(Edit1.Text) then
     begin
     queryperformancefrequency(Tf);
     queryperformancecounter(T0);
     ms.LoadFromFile(Edit1.text);
     queryperformancecounter(T1);
     setlength(s,ms.size);
     ms.Position := 0;
     ms.ReadBuffer(s[1],ms.size);
     queryperformancecounter(T2);
     memo1.Lines.Text:=s;
     queryperformancecounter(T3);
     pCr := ms.memory;
     i := Cardinal(pCr);
     EndPos :=i+ms.Size;
     StartPos:= i;

     repeat
       if pChar(i)^ = #13 then
         begin
         inc(i);
         if pChar(i)^ =#10 then
           begin
           l := i-Startpos-1;
           setlength(s,l);
           move(pChar(Startpos)^,S[1],l);
           {Verarbeiten...}
           inc(i);
           startPos := i;
           end;
         end;
       inc(i)
     until i >EndPos;
     queryperformancecounter(T4);
     memo1.Lines.Add('');
     memo1.Lines.Add(s);
     s :=Format('dT1 %10.6e dt2 %10.6e dt3 %10.6e dt4 %10.6e Groesse : %10d',[ms.Size/((t1-t0)/tf),ms.Size/((t2-t1)/tf),ms.Size/((t3-t2)/tf),ms.Size/((t4-t3)/tf),ms.size]);
     memo1.Lines.Add(s);
     end;
  ms.Free;
end;
{
Ergebnis fuer eine 91671 und 1399 Zeilen (Bootlog.txt)
dT1 1,85810E+008 dt2 5,83880E+008 dt3 3,52691E+006 dt4 1,20773E+008 Groesse :      91671}

also grob:
Einlesen Stringstream 185 Mb/s (Cached)
in String kopieren 583 Mb/s
in Stringlist packen 3.5 Mb/s
nach und nach in String packen 120 Mb/s

Eine 2.6 Mb Datei mit 38863 Zeilen
dT1 3,60808E+008
dt2 2,40895E+008
dt3 5,93778E+006
dt4 1,40882E+008
Groesse : 2612155

Es ist schon ein gewaltiger Unterschied.
Also im Stream lassen ist das mit Abstand schnellste.
Aber stringlist ist nun mal einfacher in der Handhabung aber ueber 40 mal langsamer.

Gruss Horst