Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - String am Anfang eines anderen?
Flamefire - Mi 01.10.08 10:39
Titel: String am Anfang eines anderen?
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 - 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.
Delete - Mi 01.10.08 10:46
Z.B. so:
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 - 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...
Delete - 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 - 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:
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)^ and PWord(pb+4)^=PWord(pb2+4)^) |
Oder liege ich da falsch?
Delete - Mi 01.10.08 12:00
Versuch es doch einfach mal so:
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 - Mi 01.10.08 12:31
jo super idee
hab mal nen test gemacht:
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 - Mi 01.10.08 12:52
wow, dachte nicht das es da so einen performanceunterschied gibt. werd das mir mal gleich wegspeichern!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!