-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
16. Jul 2018
Das StringReplace in D2009 verwendet ja auch keinen StringBuilder und das dortige Replace, sondern in etwa folgenden Algorithmus:
1. Initialisiere Result mit einem Leerstring und setze die Position auf den Anfang des Strings
2. Suche das nächste Vorkommen des Such-Patterns
3. Hänge den String vom Start bis zur Startposition des Such-Patterns bzw. Ende des Strings (wenn nicht gefunden) an den...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
15. Jul 2018
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...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
15. Jul 2018
Solltest du nochmal überdenken. Ich habe den Code mal unter D2009 compiliert und auf meinem System ausführen lassen, diesmal allerdings nur für 10(!!!) Durchäufe (aus gleich ersichtlichen Gründen):
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
15. Jul 2018
Ich hatte bereits probeweise mal die Anzahl Durchläufe auf 100.000 erhöht und auf 1000 erniedrigt. Dabei sind die Zeiten im Bereich der bekannten Schwankungen zwischen verschiedenen Programmstarts ziemlich konsistent um den Faktor 10 verändert worden. Um einen einzelnen Aufruf zu messen reicht die Auflösung meiner Meinung nach einfach nicht aus.
Alles Win32 (die Zeiten für 100000 dauern mir...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
15. Jul 2018
Ich erweitere dann mal den Benchmark auf OSX, Linux, Android und iOS :twisted:
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
15. Jul 2018
So ganz verstehe ich noch nicht, was du mit deine avg-Berechnung genau erreichen willst. Die generelle Vorgehensweise für eine Mittelwertberechnung ergibt sich aus der Definition:
avgn := Sumi:1..n(xi)/N; // xi = Wert bei Iteration i, N Anzahl Iterationen.
Rekursiv ergibt sich daraus:
avgn+1 := (avgn*N + xn+1)/(N+1)
if Loops = 0 then
begin
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
15. Jul 2018
Ich finde, du machst es dir hier unnötig kompliziert und erhöhst zumindest potentiell die Messungenauigkeit in dem du die Zeit für jede einzelne Iteration misst. In jedem Fall erhöhst du aber die Gesamtlaufzeit des Benchmarks (nicht das Ergebnis), weil innerhalb der Schleife ein Haufen berechnet wird (zur Zeit offenbar auch noch falsch), der da gar nicht nötig wäre (z.B. wird der von...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
14. Jul 2018
Eventuell ist es effizienter, beim ersten Mal die Anzahl der Vorkommen zu ermitteln, dann das Array auf die passende Größe setzen und im zweiten Durchlauf dann die Positionen einzutragen. Mehrfache SetLength-Aufrufe wären da eher suboptimal.
Alternativ eine TList<Integer> füllen und über ToArray in ein Array umwandeln.
Man kann natürlich auch erstmal das Array mit Length(S) anlegen, wenn...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
14. Jul 2018
Steht im Source in einem der Attachments weiter oben.
type
//zentral deklariert
PStrLenInt = ^StrLenInt;
StrLenInt = {$IFDEF FPC}SizeInt{$ELSE}LongInt{$ENDIF};
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
14. Jul 2018
Nein, sowas gibt es bislang noch nicht.
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
14. Jul 2018
OK, ich hatte die -8 bei der Berechnung von PEnd übersehen. Sorry!
Die hiesigen Ergebnisse für Win32:
und für Win64:
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
14. Jul 2018
Da scheint es beim Compiler doch noch Unterschiede zu geben, aber auch der Prozessor spielt wohl eine Rolle:
... und ein direkter Weg ins Desaster, wenn die Stringlänge nicht durch 8 teilbar ist! Die Bedingung der ersten While-Schleife passt nicht so richtig, oder?
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Einmal für Win32:
und nochmal für Win64:
Nein, das glaube ich auch nicht. Der Compiler sollte derselbe sein.
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Gar nichts :-D
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Jetzt wird's aber interessant! Hier mal die Laufzeiten für Win64 (die ASM-Funktion fällt da logischerweise raus):
Der große Verlierer ist hier erstaunlicherweise StringCountChar
Result := 0;
for Ch in S do begin
Inc(Result, Ord(Ch = C));
end;
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Hier meine Ergebnisse, wobei die korrigierte Assembler-Lösung da schon einfließt. Erklären kann ich mir den Unterschied zwischen EH1 und EH2 aber auch nicht. Der erzeugte Code ist offenbar bei EH1 effizienter.
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Wie schon erwähnt, ich halte von Benchmarks mit einem einzigen Testcall nicht viel, auch nicht bei einem noch so langem Teststring. Deswegen habe ich das wie bereits beschrieben abgewandelt (siehe Anhang).
Es ist aber in der Tat so, daß es schon zwischen verschiedenen Compilaten durchaus Unterschiede geben kann, bei denen sich die Reihenfolge mancher Kandidaten vertauscht. Das ist wohl auch...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Ja, funktioniert jetzt. Allerdings ist das Zeitverhalten (mit Optimierung) noch schlechter als die Standardfunktion CountChar im StringHelper und damit landet die Lösung in der hiesigen Rangliste auf dem drittletzten Platz. Lediglich die StringReplace-Lösung und die AnsiString-Lösung (vermutlich wegen der bei jedem Aufruf nötigen Umwandlungen) sind noch langsamer.
Hier meine Zeiten für einen...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Ach ja, statt Randomize verwende ich RandSeed := 0;
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Der Fehler kommt hier auch, wenn ich die Optimierung einschalte. Der Debugger bleibt dann bei dem repnz Befehl stehen.
Mit abgeschalteter Optimierung brauchen die Pascal-Funktionen aber deutlich länger. Wobei sich dann wieder die Verwendung der internen Funktionen (StrScan oder string.CountChar) bezahlt macht, da die von dem Schalter nicht betroffen sind.
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Interessanterweise läuft die Funktion im Debug-Mode durch, aber im Release-Mode gibt es sofort eine Zugriffsverletzung. Dieser Effekt zusammen mit den Plattform-Einschränkungen und Maintenance-Problemen erzeugen zumindest bei mir eine Abwehrhaltung gegenüber jedweder ASM-Lösung. Ein eventuell signifikanter Geschwindigkeitsvorteil bliebe noch zu belegen.
Übrigens: Bei den Funktionen, die auch...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Hier z.B. ein Helper für TTextReader zum korrekten Einlesen einer CSV-Datei, bei der innerhalb der gequoteten Felder Zeilenumbrüche vorkommen.
function TTextReaderHelper.ReadQuotedLine(QuoteChar: Char): string;
var
line: string;
begin
Result := ReadLine;
if Odd(Result.CountChar(QuoteChar)) then begin
{ Eine ungerade Anzahl von Quotes bedeutet, daß der gequotete String...
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Aber genau das ist hier passiert als ich die Funktion ausführen wollte.
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Im Wesentlichen macht TStopWatch ja auch nichts anderes. Es geht ja auch nicht um die absoluten Werte, sondern um die Vergleichbarkeit.
-
Forum: Sonstige Fragen zu Delphi
Delphi
by Uwe Raabe,
13. Jul 2018
Mein Kommentar bezogt sich auf die Originalversion.