有一个版本的StrToInt?

WeG*_*ars 5 delphi

似乎StrToInt没有Ansi重载.这是正确的吗?或许我错过了一些东西.StrToInt坚持将我的ansistrings转换为字符串.

Dav*_*nan 7

你是对的.没有ANSI版本StrToInt.找到标准功能的ANSI版本的地方就是AnsiStrings单位,那里什么也没有.

编写自己的函数来完成工作,或接受使用所需的转换StrToInt.

编写自己的函数并不难.它可能看起来像这样:

uses 
  SysConst; // for SInvalidInteger
....
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
function AnsiStrToInt(const s: AnsiString): Integer;

  procedure Error;
  begin
    raise EConvertError.CreateResFmt(@SInvalidInteger, [s]);
  end;

var
  Index, Len, Digit: Integer;
  Negative: Boolean;
begin
  Index := 1;
  Result := 0;
  Negative := False;
  Len := Length(s);
  while (Index <= Len) and (s[Index] = ' ') do
    inc(Index);
  if Index > Len then
    Error;
  case s[Index] of
  '-','+':
    begin
      Negative := s[Index] = '-';
      inc(Index);
      if Index > Len then
        Error;
    end;
  end;
  while Index <= Len do
  begin
    Digit := ord(s[Index]) - ord('0');
    if (Digit < 0) or (Digit > 9) then
      Error;
    Result := Result * 10 + Digit;
    if Result < 0 then
      Error;
    inc(Index);
  end;
  if Negative then
    Result := -Result;
end;
Run Code Online (Sandbox Code Playgroud)

这是发现的缩减版本StrToInt.它不处理十六进制,并且在错误方面更严格一些.在使用此代码之前,我想测试这是否真的是您的瓶颈.

非常有趣的是,此代码基于RTL源中的代码,无法返回low(Integer).解决这个问题并不难,但这会使代码更加复杂.

  • 将是那么糟糕.当然你的程序是磁盘绑定而不是CPU绑定.你测量了吗? (4认同)
  • 你真正需要的是一个函数,它将一行作为输入并返回一个值数组.更好的是,你传入一个预先分配的数组,最好是在堆栈上,如果可能的话,函数会一次性拆分和填充,而不会触及堆.请记住,当你想要方便时,堆是你的朋友,但是当你关心perf时,你的死敌. (4认同)
  • @Altar:但是你只进行一次StrToInt转换,对吧?所以这不是瓶颈.磁盘I/O将是比计算更大的瓶颈. (3认同)
  • @Altar如果你确实在这里遇到了瓶颈,那么我准备打赌它会在堆分配上.将分隔符上的行拆分为单独的值,从而导致堆载荷分配.它们将在文本转换为int转换时至少维持一个数量级的perf.我确实怀疑你并不是真正的性能瓶颈. (2认同)