Einzelnen Beitrag anzeigen

EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#147

AW: Anzahl eines Zeichens im String ermitteln

  Alt 16. Jul 2018, 05:20
Um etwas zu lernen, hilft es mir es zu verstehen. Schnell im Pure-Pascal ist etwas, was ich mag.
Wenn ich mir die Implementation von StringReplace in D2009 und Tokyo ansehe, dann sind die doch schon sehr verschieden. Die Implementation in D2009 (34 Zeilen) macht einen Haufen Copy und Result := Result + NewStr, während Tokyo (212 Zeilen) zunächst die Anzahl der Fundstellen ermittelt und damit die Länge von result ermittelt und bereitstellt. Danach wird einfach nur mehrfach ein Move in Result gemacht. Das ist unterm Strich offenbar deutlich schneller. Der Code in 2009 ist dafür leichter zu verstehen und straight forward. In der Tokyo Version möchte ich keinen Fehler suchen.
So was habe ich mir schon gedacht.. für das Abändern der function! Ich kenne sehr viele implementationen von StringReplace, alle jedoch reservieren Speicher für das Resultat. Hier kommt noch eine Sache zum Tragen: der Char ist kein String, somit sollte abermals Speicher (WideChar->UnicodeString) reserviert werden, wenn da nicht inzwischen ein overload existiert. Gehen wir davon aus, die neue Variante wurstelt erst mal die Anzahl der vorgekommenen SubStr's raus, hat einen statischen Pool von Markern vorreserviert, und braucht nur noch in das Result schreiben(wenn Result string refcount 1 ist). SysFreeMem und SysGetMem setzen/flushen nur (dank Idee von Pierre le Richie -> verzögertes freigeben ) noch das Flag für den Speicherbereich(oder hält der Compiler das Result auf alle Ewigkeit im Speicher?). Kling alles sehr gut!

Dennoch stehen die Calls(50Cycles/Call) auf StringReplace, ?WChar2UStr?, GetMem, FreeMem und 240 Zeilen StringReplace im Raum (Length ist seit D2005 inlined und macht das gleiche, wie mein NativeCode oder es in den ASM varianten zu sehen ist) und 2x Code für die Stringlänge, wogegen jede andere function ohne all dem auskommt. Ich meine man sollte da schon einen merklichen Nachteil erkennen können. Darum die Hypothese. Und die An,erkung über den Test Selber, das der String in seiner Größe und Inhalt permanent wechseln sollte. Wäre dem so(IMHO usual case), würde sich die StringReplace Variante auch auf dem neuen Compiler deutlich mehr abheben und die Nachteile erleutern (der Lerneffekt für andere Benutzer sollte ja gegeben sein, oder?).

Ich bin dennoch sehr beeindruckt, wie weit der Compiler Fortschritte für Optimierungen all der Schritte inzwischen gemacht hat. Würde mir ein Chart wünschen, welches solche Effeckte je nach Compiler-Entwicklungsforschritt(alt vs. neu) mal darstellt. Gibt es ein solches? Es gäbe mit Sicherheit eine Ziehlgruppe, die solche Darstellungen eher zum Kauf/Update bewegen würden als FMX,Generics,NEXTGEN &Co.

Aber danke auch an Dich für den Hinweis mit der blockweisen Bearbeitung, da kommen mir Ideen für andere Funktionen (z.B. in der Bitmap-Bearbeitung)...
Gern geschehen. Auch die 2. ASM Variante von Andreas zeigt die Technik auf (viel genialer umgesetzt dank seiner ASM Kenntnisse). Der Effeck einer Blockweisen Abarbeitung innerhalb einer Big-Loop wird deutlich größer, desto mehr insgesammt verarbeitet wird. Das Thema hier ist da von der Aufgabenstellung her zu maginal für meine Pure-Pascal Version um den Effekt aufzuzeigen zu können. Es entsteht jedoch deutlich mehr Code der gepflegt werden muß, also macht die Technik auch nicht überall Sinn, könnte sich sogar negativ auswirken. Hinzu kommt das viele den Sinn nicht erkennen können. Da gibt es Leute, die fangen mit 'nem Thread-Pool/TParallel an, wo diese Technink schon ausreichend oder effizienter wäre.

Geändert von EgonHugeist (16. Jul 2018 um 06:22 Uhr)
  Mit Zitat antworten Zitat