![]() |
Re: Meine Explode-Funktion optimieren
Zitat:
der Ansatz ist ja klasse. Den merke ich mir. Manchmal kann das Leben so einfach sein;-) Aber! Vorher sollte geprüft werden, ob nicht zufällig das Komma im Text vorhanden ist. Da hätte man ja sonst eine falsche Teilung. Gerd |
Re: Meine Explode-Funktion optimieren
Hallo Gerd,
hat denn meine Funktion bei dir einen Fehler produziert, wenn Kommata Textbestandteil sind? Freundliche Grüße |
Re: Meine Explode-Funktion optimieren
Zitat:
|
Re: Meine Explode-Funktion optimieren
Zitat:
Dein Code bringt tatsächlich in keiner Situation einen Fehler. Perfekt. Gerd |
Re: Meine Explode-Funktion optimieren
mir fällt auf dass, das Ergebnis mit
String = String + Irgendwas in einer Schleife zusammengesetzt wird. Es ist bedeutend schneller die größe des benötigten Speichers einmal zu setzen und den Speicher in einem rutsch zu kopieren als in vielen kleinen happen. |
Re: Meine Explode-Funktion optimieren
Hier mal eine Version (eben schnell geschrieben), die auf einem stark vereinfachten String-Matching-Algorithmus von Boyer-Moore basiert. Anstatt die gefundene Position zurückzuliefern, wird der Text extrahiert und in eine TStringlist geschrieben
Delphi-Quellcode:
Interessant ist, das hier nicht jedes Zeichen des Textes geprüft wird. Wenn man z.B. nach 'ABC' sucht, und der 3.Buchstabe ist kein 'C', kann man ja gleich um 3 Zeichen nach vorne gehen. Je länger der Suchtext ist, desto besser die Performance. Natürlich kann man ihn reinlegen (aPattern = 'aaaaaaaa').
Procedure AlzExplode(Const aText, aPattern: String; aItems: TStrings);
(*----------------------------------------------------------------------------- * Spaltet Textteile in aText, die durch aPattern getrennt sind auf, und * füllt die einzelnen Texte in aItems. * <del>abc<del>xyz => ('abc','xyz') * Basiert auf der QuickSearch-Implementierung von * Christian Charras und Thierry Lecroq, Université de Rouen, * 76821 Mont-Saint-Aignan Cedex * Frankreich *) Var i0, i, k, n, m: Cardinal; c: Char; Skip: Array[Char] Of Integer; Begin aitems.clear; m := Length(aPattern); If m = 0 Then Exit; // Sprungtabelle für nicht übereinstimmende Zeichen erstellen For c := Low(Char) To High(Char) Do Skip[c] := m + 1; For i := 1 To m Do Skip[aPattern[i]] := m - i + 1; i := 1; i0 := 1; n := Length(aText); k := n - m + 1; While i <= k Do Begin If (aPattern[1] = aText[i]) And (aPattern[m] = aText[i + m - 1]) Then // <<--- von DJ-SPM If CompareMem(@aText[i], @aPattern[1], m) Then Begin aItems.Add(Copy(aText, i0, i - i0)); inc(i, m); i0 := i; Continue; End; inc(i, Skip[aText[i + m]]); End; If i0 <= n Then aItems.Add(Copy(aText, i0, n - i0 + 1)); End; Sicherlich gibt es noch bessere Algorithmen (Boyer-Moore, Raita, etc.) aber der o.g. ist schön kompakt und wirklich flott. Die Abfrage nach dem ersten und letzten Buchstaben des Patterns, vor dem eigentlichen CompareMem, ist von DJ-SPM übernommen. Das scheint enorm viel zu bringen. Diese Version ist nochmal 50% schneller als die von DJ-SPM. Allerdings hatte ich nicht seine Original-Version genommen (die ja nicht ganz korrekt ist), sondern noch ein 'CompareMem' eingebaut. Wer hat Lust, hier weiter zu optimieren? Derzeit ist es ja schon eine echte Gemeinschaftsarbeit von DJ-SPM und den Franzosen (ok, ein wenig auch von mir). Das wäre dann die ultimative Explode-Funktion... Kleiner Nachtrag: Die Version schlägt die CodeLib-Version um den Faktor 1,5-16. Die CodeLib-Version degeneriert zudem bei kurzen SuchStrings (Delimiter bzw. Pattern). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz