Eine eigene Implementation:
Code: Alles auswählen
function isIntLoop(s: String): Boolean; inline;
var
i: Integer;
begin
Result := Length(s) > 0;
for i:=1 to Length(s) do
if not (s[i] in ['0'..'9']) then
exit(False);
end;
Code: Alles auswählen
function isIntVal(s: String): Boolean; inline;
var dummy: Integer;
code: Word;
begin
val(s, dummy, code);
Result := code = 0;
end;
Code: Alles auswählen
function strToIntExample(s: String): Integer;
var
i: Integer;
begin
if Length(s) = 0 then error;
Result := 0;
for i:=1 to Length(s) do
begin
Result *= 10;
if (s[i] in ['0'..'9']) then
Result += ord(s[i]) - ord('0')
else
error
end;
end;
Würde man LLVM als backend benutzen könnte der Optimizer wahrscheinlich bei Whole-Program optimization feststellen das das ergebnis von val nicht verwendet wird und dieses wegoptimieren (sodass man dann bei der selben funktionaltiät wie die handgeschriebene funktion endet), allerdings ist der FPC Optimizer nicht so gut wie LLVM, weshalb dieser unterschied zu stande kommt.
Was mir dabei auch aufgefallen ist, ein For-in loop ist deutlich langsamer als ein For-i loop. also mein beispiel von oben
Code: Alles auswählen
function IsInteger(s: string): boolean; inline;
var
c: char;
begin
Result := s.length > 0;
for c in s do
if not (c in ['0'..'9']) then
exit(False); // oder Result := False; und break;
end;
Da die meisten Pascal programme allerdings nicht auf optimale performance aus sind, ist das meist kein Problem, sollte man nur im Hinterkopf behalten, das sich der FPC nicht so sehr für performance kritische anwendungen eignet
Programm:
Code: Alles auswählen
program Project1;
{$mode objfpc}{$H+}
uses
LCLIntf;
type TStringArray = array of String;
type TBooleanArray = array of Boolean;
function GenRandomString: String;
var
len, i: integer;
begin
len := Random(4) + 2;
SetLength(Result, len);
for i:=1 to len do
Result[i] := chr(Random(15) + ord('0'));
end;
function GenRandomStrings(n: Integer): TStringArray;
var
i: Integer;
begin
SetLength(Result, n);
for i:=0 to n-1 do
Result[i] := GenRandomString;
end;
function isIntVal(s: String): Boolean; inline;
var dummy: Integer;
code: Word;
begin
val(s, dummy, code);
Result := code = 0;
end;
function isIntLoop(s: String): Boolean; inline;
var
i: Integer;
begin
Result := Length(s) > 0;
for i:=1 to Length(s) do
if not (s[i] in ['0'..'9']) then
exit(False);
end;
var
arr: TStringArray;
valResults: TBooleanArray;
loopResults: TBooleanArray;
start: Cardinal;
valTime, loopTime: Cardinal;
i: Integer;
begin
Randomize;
arr := GenRandomStrings(10000000);
SetLength(valResults, Length(Arr));
SetLength(loopResults, Length(Arr));
start := GetTickCount;
for i:=0 to Length(arr) -1 do
loopResults[i] := isIntLoop(arr[i]);
loopTime := GetTickCount-start;
start := GetTickCount;
for i:=0 to Length(arr) -1 do
valResults[i] := isIntVal(arr[i]);
valTime := GetTickCount-start;
WriteLn('Val: ', valTime);
WriteLn('loop: ', loopTime);
end.