Autor Beitrag
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 01.10.08 10:39 
Hallo,
ich habe einen stringvergleich, der sehr häufig ausgeführt werden muss
darum die Frage, was das schnellste (Ausführung) ist.

Es geht darum, dass ein String am Anfang eines anderen sein soll: z.B. "abc" ind "abcde" aber nicht ind "deabc"
Pos() würde den ganzen string durchsuchen-->unperformant

Habs z.Zt. so:
Copy(sTarget,1,Length(sSuch))<>sSuch

wobei sSuch ne konstante ist

aber vermutlich ist das sogar noch langsamer...

Was wäre die beste?
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mi 01.10.08 10:44 
In den StrUtils gibt es Funktionen AnsiStartsText und AnsiStartsStr (evtl. ohne das s in Starts und/oder leicht anders) - der Unterschied liegt bei der Berücksichtigung von Groß- und Kleinschreibung.

Oder halt eine eigene kleine Funktion schreiben. Mit einer Schleife, die sofort abbricht, sobald ein Zeichen nicht übereinstimmt.

_________________
We are, we were and will not be.
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 01.10.08 10:46 
Z.B. so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function StartsWith(const s, Pattern: string): Boolean;
var i: integer;
begin
  i := 0;
  Result := Length(Pattern) <= Length(s);
  while (i < Length(Pattern)) and Result do
    begin
      inc(i);
      Result := s[i] = Pattern[i];
    end;
end;
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 01.10.08 11:10 
Die funtion von DeddyH sieht nicht schlecht aus
wie funktioniert der Zugriff auf String[x]?
Wäre man vl mit Pointern schneller? Oder ist das schon das gleiche?

Die funktionen ansistarts...() sind das gleiche was ich auch schon gemacht hab...
nur vermutlich noch langsamer...
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 01.10.08 11:15 
Pointer oder Streams wären vermutlich noch schneller. Du könntest z.B. beide Strings in jeweils einen Stream laden, der die Länge Length(Pattern) hat. Nun könntest Du mit CompareMem vergleichen. Und die Frage nach dem Zugriff auf String[x] habe ich nicht verstanden, was meinst Du?
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 01.10.08 11:30 
also der string hat eine Länge von ca. 10-15 Zeichen. bei streams würde ich denken, dauert es zu lange...weil der stream muss ja erst erstellt werden, dann verglichen etc...

und so weit ich weiß ist ein string einfach nur ein pchar
sprich: der string ist ein pointer auf eine zeichenfolge

man könnte also: Länge vergleichen (von dem einen ist es ja ne konstante)
und dann jeweils 4-byte bis 2- und 1-byte weise den inhalt der pointer vergleichen

also so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
s:='String';
s2:='String2';
pb:=Cardinal(Pointer(s));
pb2:=Cardinal(Pointer(s2));
If(PCardinal(pb)^=PCardinal(pb2)^ //Zeichen 1-4 ('Stri')
  and PWord(pb+4)^=PWord(pb2+4)^) //Zeichen 5-6 ('ng')


Oder liege ich da falsch?
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 01.10.08 12:00 
Versuch es doch einfach mal so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function StartsWith(const s, Pattern: string): Boolean;
begin
  Result := Length(Pattern) <= Length(s);
  if Result then
    Result := CompareMem(PChar(s),PChar(Pattern),Length(Pattern));
end;
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 01.10.08 12:31 
jo super idee
hab mal nen test gemacht:
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:
procedure TfrmMain.Button1Click(Sender: TObject);
var i,k:Integer;j:Cardinal;
    s,str1:String;
begin
  str1:='TestString';
  s:='TestString1';
  j:=GetTickCOunt;
  k:=0;
  for i:=0 to 9999999 do begin
    If(Copy(s,1,Length(str1))=str1) then Inc(k);
  end;
  s:='Test134';
  for i:=0 to 9999999 do begin
    If(Copy(s,1,Length(str1))=str1) then Inc(k);
  end;
  Caption:=inttostr(GetTickDiff(j,GetTickCOunt))+' '+inttostr(k);
end;

procedure TfrmMain.Button2Click(Sender: TObject);
var i,k:Integer;j:Cardinal;
    s,str1:String;
begin
  str1:='TestString';
  s:='TestString1';
  j:=GetTickCOunt;
  k:=0;
  for i:=0 to 999999 do begin
    If(CompareMem(Pointer(s),Pointer(str1),Length(str1))) then Inc(k);
  end;
  s:='Test134';
  for i:=0 to 999999 do begin
    If(CompareMem(Pointer(s),Pointer(str1),Length(str1))) then Inc(k);
  end;
  Caption:=inttostr(GetTickDiff(j,GetTickCOunt))+' '+inttostr(k);
end;


Ergebnis: Methode 1: ~3300
Methode 2: ~80(!!!)

Also: Gelöst!
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Mi 01.10.08 12:52 
wow, dachte nicht das es da so einen performanceunterschied gibt. werd das mir mal gleich wegspeichern!

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.