Mich hat die Funktion "longestNumber" aus #42 interessiert.
Wegen des Kommentars
Zitat:
Unter Performanzgesichtspunkten mag das eventuell (messbar?) langsamer sein.
wollte ich das mal testen.
Hierfür habe ich mit von
www.geonames.org die Datei "allCountries.txt" herunter geladen.
Das ist eine UTF8-codierte Datei (ohne BOM), die ca. 12 Mio LF-terminierte Zeilen enthält.
Die Dateigröße ist 1,563,600,457 Bytes.
Die habe ich in einen AnsiString geladen, auf den ich die Funktionen aus #37, #42 und #47 losgelassen habe.
Da die Funktionen mit Strings arbeiten, habe ich folgende Änderungen vorgenommen:
Bei #37 Parameter auf const S:AnsiString und Result auf AnsiString geändert.
Bei #42 dto und zusätzlich die lokalen Variablen "NumberStr" und "longNumStr" :auf AnsiString geändert.
Bei #47 Parameter und das Result auf AnsiString geändert und die PChars auf PAnsiChar.
Das Ergebnis:
Code:
Länge von S = 1563600457
Zeit: 2683 ms "0020120010067" LaengsteZiffernFolgeDerWelt (Michael II #37)
Zeit: 0 ms "2986043" longestNumber (Delphi.Narium #42)
Zeit: 2137 ms "0020120010067" LongestCipherSequence (Amateurprofi #47)
#42 braucht 0 ms was deutlich schneller ist als #37 und #47, liefert aber ein anderes Ergebnis als die beiden anderen Funktionen, die wiederum identische Ergebnisse liefern.
Hat mich na klar interessiert warum die so schnell ist.
Grund: die Variable "run" ist als Byte deklariert, was bei der Länge von S = 1563600457 ($5D32A649) bedeutet, dass nur die ersten $49 (73) Zeichen geprüft werden.
Also habe ich die Deklaration von "run" auf Integer geändert.
Ein erneuter Testlauf brachte dann
Code:
Länge von S = 1563600457
Zeit: 2699 ms "0020120010067" LaengsteZiffernFolgeDerWelt (Michael II #37)
Zeit: 21076 ms "0020120010067" longestNumber (Delphi.Narium #42)
Zeit: 2262 ms "0020120010067" LongestCipherSequence (Amateurprofi #47)
Jetzt liefern alle Funktion das gleiche Ergebnis aber #42 braucht 8 bis 9 mal so viel Zeit wie die beiden anderen Funktionen, was den Kommentar
Zitat:
Unter Performanzgesichtspunkten mag das eventuell (messbar?) langsamer sein.
bestätigte.
Die Testprozedur
Delphi-Quellcode:
PROCEDURE TMain.Test;
FUNCTION NStr(V:Cardinal; L:Integer):
String;
begin
Result:=IntToStr(V);
Result:=StringOfChar(#$2007,L-Length(Result))+Result;
end;
FUNCTION SStr(
const S:AnsiString; L:Integer):
String;
begin
Result:='
"'+S+'
"'+StringOfChar(#$2007,L-Length(S));
end;
const
F1='
LaengsteZiffernFolgeDerWelt (Michael II #37)';
F2='
longestNumber (Delphi.Narium #42)';
F3='
LongestCipherSequence (Amateurprofi #47)';
var NL,SL,SLen:Integer;
T0,T1,T2,T3:Cardinal;
Size:Int64;
Dsn:
String;
S,S1,S2,S3:AnsiString;
Stream:TFileStream;
begin
Stream:=Nil;
try
try
Dsn:=FilePath(BaseFilesPath,AllCountriesDsn,True);
Stream:=TFileStream.Create(Dsn,fmOpenRead
or fmShareExclusive);
Size:=Stream.Size;
if Size>MaxInt
then
raise Exception.Create('
Datei kann nicht geladen werden, ist zu groß');
SetLength(S,Size);
Stream.
Read(S[1],Size);
ShowMessage('
Datei geladen. Test beginnt mit OK');
T0:=GetTickCount;
// LaengsteZiffernFolgeDerWelt
S1:=LaengsteZiffernFolgeDerWelt(S);
T1:=GetTickCount;
// longestNumber
S2:=longestNumber(S);
T2:=GetTickCount;
// LongestCipherSequence
S3:=LongestCipherSequence(S);
T3:=GetTickCount;
SLen:=Length(S);
S:='
';
Dec(T3,T2);
Dec(T2,T1);
Dec(T1,T0);
NL:=Length(IntToStr(Max(Max(T1,T2),T3)));
SL:=MaxIntValue([Length(S1),Length(S2),Length(S3)]);
ShowMessage('
Länge von S = '+IntToStr(SLen)+#13+
'
Zeit: '+NStr(T1,NL)+'
ms '+SStr(S1,SL)+'
'+F1+#13+
'
Zeit: '+NStr(T2,NL)+'
ms '+SStr(S2,SL)+'
'+F2+#13+
'
Zeit: '+NStr(T3,NL)+'
ms '+SStr(S3,SL)+'
'+F3);
except
on E:
Exception do ShowMessage(E.
Message);
end;
finally
Stream.Free;
end;
end;