Hallo Robert,
ich habe Deinen Vorschlag als pure Pascal-Lösung (VI) implementiert:
Delphi-Quellcode:
function AnsiToAsciiCharMapping(const AnInput: string): string;
var
iChar: Integer;
begin
SetLength(Result, Length(AnInput));
for iChar:= Length(Result) downto 1 do
Result[iChar]:= CharMap[Result[iChar]];
end;
wobei ich die Tabelle wg des "Test-Frameworks" leider nicht als Parameter übergeben kann.
Mit einer Signatur der Form
function AnsiToAsciiCharMapping(const AMap: TCharacterMap; const AnInput: string): string;
wäre bei einer flexibleren Lösung im erzeugen Code demnach eine weitere Indirektion statt eines konstanten Displacements der Art
vorhanden...
Die Ergebnisse des Laufes mit String der Länge 8 im Vergleich zu (IV) und (V)
Code:
Created 131072 random strings (len: 8)
Each function (3) returns same result
PChar (IV) [Run 1]: 50 msec (2570039 per sec)
PChar (IV) [Run 2]: 50 msec (2570039 per sec)
PChar (IV) [Run 3]: 50 msec (2570039 per sec)
PChar (IV) [Run 4]: 40 msec (3196878 per sec)
PChar (IV) [Run 5]: 50 msec (2570039 per sec)
PChar (IV) [Run 6]: 40 msec (3196878 per sec)
PChar (IV) [Run 7]: 50 msec (2570039 per sec)
PChar (IV) [Run 8]: 51 msec (2520615 per sec)
PArith (V) [Run 1]: 50 msec (2570039 per sec)
PArith (V) [Run 2]: 50 msec (2570039 per sec)
PArith (V) [Run 3]: 60 msec (2148721 per sec)
PArith (V) [Run 4]: 60 msec (2148721 per sec)
PArith (V) [Run 5]: 50 msec (2570039 per sec)
PArith (V) [Run 6]: 60 msec (2148721 per sec)
PArith (V) [Run 7]: 60 msec (2148721 per sec)
PArith (V) [Run 8]: 50 msec (2570039 per sec)
CMapping (VI) [Run 1]: 50 msec (2570039 per sec)
CMapping (VI) [Run 2]: 40 msec (3196878 per sec)
CMapping (VI) [Run 3]: 50 msec (2570039 per sec)
CMapping (VI) [Run 4]: 40 msec (3196878 per sec)
CMapping (VI) [Run 5]: 61 msec (2114064 per sec)
CMapping (VI) [Run 6]: 50 msec (2570039 per sec)
CMapping (VI) [Run 7]: 50 msec (2570039 per sec)
CMapping (VI) [Run 8]: 50 msec (2570039 per sec)
der wirkliche Geschwindikeitsvorsprung des Mappings gegenüber der bisher schnellsten Pascal-Lösung (V) kommt erst bei längeren Strings (hier: 512 Zeichen) zum Vorschein:
Code:
Created 131072 random strings (len: 512)
Each function (3) returns same result
PChar (IV) [Run 1]: 631 msec (207392 per sec)
PChar (IV) [Run 2]: 630 msec (207721 per sec)
PChar (IV) [Run 3]: 641 msec (204161 per sec)
PChar (IV) [Run 4]: 631 msec (207392 per sec)
PChar (IV) [Run 5]: 641 msec (204161 per sec)
PChar (IV) [Run 6]: 641 msec (204161 per sec)
PChar (IV) [Run 7]: 631 msec (207392 per sec)
PChar (IV) [Run 8]: 641 msec (204161 per sec)
PArith (V) [Run 1]: 1472 msec (88983 per sec)
PArith (V) [Run 2]: 1472 msec (88983 per sec)
PArith (V) [Run 3]: 1472 msec (88983 per sec)
PArith (V) [Run 4]: 1482 msec (88383 per sec)
PArith (V) [Run 5]: 1463 msec (89530 per sec)
PArith (V) [Run 6]: 1482 msec (88383 per sec)
PArith (V) [Run 7]: 1472 msec (88983 per sec)
PArith (V) [Run 8]: 1462 msec (89591 per sec)
CMapping (VI) [Run 1]: 1031 msec (127007 per sec)
CMapping (VI) [Run 2]: 1032 msec (126884 per sec)
CMapping (VI) [Run 3]: 1021 msec (128250 per sec)
CMapping (VI) [Run 4]: 1032 msec (126884 per sec)
CMapping (VI) [Run 5]: 1021 msec (128250 per sec)
CMapping (VI) [Run 6]: 1022 msec (128125 per sec)
CMapping (VI) [Run 7]: 1031 msec (127007 per sec)
CMapping (VI) [Run 8]: 1042 msec (125668 per sec)
Die Ergebnisse der Unteraufrufe
Code:
Routine Name | % Time w C | Hit Count
--------------+------------+----------
UniqueStringA | 52,42 | 1048576
body only | 22,19 | 131072
LStrSetLength | 20,29 | 131072
LStrLen | 5,09 | 262144
Ergebnisse für (CMapping)
deuten an, dass eine Lösung ohne die String-Implementierung von Delphi (zB mit
PChar bzw
ASM) das Verfahren deutlich beschleuningen sollte!
Damit ist die Lösung (VI) mit einer Tabelle die bisher effizienteste bei Problemstellungen, zu denen es keine
API-Funktionen gibt. Darüber hinaus offeriert sie den Charm, einer gänzlich flexiblen Lösung: Zeichenrelation selbst kann vollständig zur Laufzeit erstellt werden.