我正在移植一些应用程序从32位到64位的delphi,它做了很多文本处理,并注意到处理速度的极大变化。例如,使用几个过程进行了一些测试,例如,64位中的时间已经超过了编译为32的时间的200%(与〜900相比,为2000 ms)
这是正常吗?
function IsStrANumber(const S: AnsiString): Boolean; var P: PAnsiChar; begin Result := False; P := PAnsiChar(S); while P^ <> #0 do begin if not (P^ in ['0'..'9']) then Exit; Inc(P); end; Result := True; end; procedure TForm11.Button1Click(Sender: TObject); Const x = '1234567890'; Var a,y,z: Integer; begin z := GetTickCount; for a := 1 to 99999999 do begin if IsStrANumber(x) then y := 0;//StrToInt(x); end; Caption := IntToStr(GetTickCount-z); end;
解决方法
64位中的测试p ^ in [‘0’…’9’]很慢。
添加了一个内联函数,带有下/上边界的测试,而不是in []测试,加上一个空字符串的测试。
function IsStrANumber(const S: AnsiString): Boolean; inline; var P: PAnsiChar; begin Result := False; P := Pointer(S); if (P = nil) then Exit; while P^ <> #0 do begin if (P^ < '0') then Exit; if (P^ > '9') then Exit; Inc(P); end; Result := True; end;
基准结果:
x32 x64 -------------------- hikari 1420 3963 LU RD 1029 1060
在32位中,主速度差为内联,并且P:= PAnsiChar(S);将在分配指针值之前调用一个外部RTL例程用于零检查,而P:= Pointer(S);只是分配指针。
观察到这里的目标是测试一个字符串是否是一个数字,然后将其转换,
为什么不使用RTL TryStrToInt()
,这一切都在一个步骤,处理标志,空白以及。