Delphi XE2 64位在字符串例程中运行时性能非常慢

我正在移植一些应用程序从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(),这一切都在一个步骤,处理标志,空白以及。

通常当分析和优化程序时,最重要的是找到正确的方法解决问题。

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...