Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.166 Beiträge
 
Delphi 12 Athens
 
#17

AW: Gibt es einen schnelleren Stringvergleich als if S1 = S2

  Alt 16. Sep 2012, 06:33
Ja, das müssen sie, aber darum muß man ja auch wissen was wie wo verglichen werden soll,

denn wenn man z.B. etwas in einer Liste suchen will, dann kann man die meisten Hashs schon vorberechnen (von allem in der Liste) und die Hashliste sogar noch sortieren.
Nun muß man nur noch den einen String hashen und kann dann ganz schnell in der Liste suchen, oder eben BTrees und Co., wo der String dann nicht erstmal komplett gehasht werden muß, sondern man nur stückchenweise in den Listen sucht, vorzeitig abbrechen kann.

Auch der Stringvergleich vom Delphi vergleicht zuerst die Länge.
Schematisch gesehn macht s1 = s2 auch nichts Anderes:
Delphi-Quellcode:
if Pointer(s1) = Pointer(s2) then Exit(True); // ich weiß nicht, ob das in der Delphi-Implementation mit drin ist, aber ist zur Erkennung auf "identische" String-Instanzen
if Pointer(s1) = nil then l1 := 0 else l1 := (PInteger(s1) - SizeOf(Integer))^;
if Pointer(s2) = nil then l2 := 0 else l2 := (PInteger(s2) - SizeOf(Integer))^;
Result := (l1 = l2) and ((l1 = 0) or CompareMem(Pointer(s1), Pointer(s2), l1 * SizeOf(s1[1])));

// und um noch ein paar Sprünge einzusparen + s1='' wird eh in einen Nil-Vergleich optimiert:
if Pointer(s1) = Pointer(s2) then Exit(True);
l1 := 0; if s1 <> 'then l1 := (PInteger(s1) - SizeOf(Integer))^; // oder einfach nur l1 := Length(s1); ... wird Length eigentlich inline compiliert?
l2 := 0; if s2 <> 'then l2 := (PInteger(s2) - SizeOf(Integer))^;
//Result := (l1 = l2) and ((l1 = 0) or CompareMem(Pointer(s1), Pointer(s2), l1 * SizeOf(s1[1])));
Result := (l1 = l2) and ((l1 = 0) or ((PLongWord(s1)^ = PLongWord(s2)^) and CompareMem(Pointer(s1), Pointer(s2), l1 * 2))); // WideChar + vergleicht extra nochmal die ersten 1-2 Chars, ohne zu CompareMem zu springen
Result := (l1 = l2) and ((l1 = 0) or ((PWord(s1)^ = PWord(s2)^) and CompareMem(Pointer(s1), Pointer(s2), l1 * SizeOf(s1[1])))); // AnsiChar oder WideChar
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (16. Sep 2012 um 14:20 Uhr)
  Mit Zitat antworten Zitat