gpt4 book ai didi

delphi - 在 Delphi 中解析一行的最快方法是什么?

转载 作者:行者123 更新时间:2023-12-03 14:40:36 26 4
gpt4 key购买 nike

我有一个巨大的文件,我必须逐行解析它。速度至关重要。

行的示例:

Token-1   Here-is-the-Next-Token      Last-Token-on-Line
^ ^
Current Position
Position after GetToken

调用 GetToken,返回“Here-is-the-Next-Token”并将 CurrentPosition 设置为 token 最后一个字符的位置,以便为下一次调用 GetToken 做好准备。 token 由一个或多个空格分隔。

假设该文件已位于内存中的 StringList 中。它很容易装入内存,例如 200 MB。

我只担心解析的执行时间。在 Delphi (Pascal) 中什么代码会产生绝对最快的执行速度?

最佳答案

  • 使用 PChar 递增来提高处理速度
  • 如果不需要某些 token ,则仅按需复制 token 数据
  • 实际扫描字符时将 PChar 复制到局部变量
  • 将源数据保留在单个缓冲区中,除非您必须逐行处理,即使如此,也请考虑将行处理作为词法分析器识别器中的单独标记进行处理
  • 如果您确实知道编码,请考虑处理直接来自文件的字节数组缓冲区;如果使用 Delphi 2009,请使用 PAnsiChar 而不是 PChar,除非您知道编码是 UTF16-LE。
  • 如果您知道唯一的空格是 #32(ASCII 空格),或类似的有限字符集,则可能有一些巧妙的位操作技巧,可以让您使用整数扫描一次处理 4 个字节。不过,我不希望在这里取得重大胜利,而且代码会像泥一样清晰。

这是一个示例词法分析器,应该非常高效,但它假设所有源数据都在单个字符串中。由于标记很长,重新处理它来处理缓冲区是相当棘手的。

type
TLexer = class
private
FData: string;
FTokenStart: PChar;
FCurrPos: PChar;
function GetCurrentToken: string;
public
constructor Create(const AData: string);
function GetNextToken: Boolean;
property CurrentToken: string read GetCurrentToken;
end;

{ TLexer }

constructor TLexer.Create(const AData: string);
begin
FData := AData;
FCurrPos := PChar(FData);
end;

function TLexer.GetCurrentToken: string;
begin
SetString(Result, FTokenStart, FCurrPos - FTokenStart);
end;

function TLexer.GetNextToken: Boolean;
var
cp: PChar;
begin
cp := FCurrPos; // copy to local to permit register allocation

// skip whitespace; this test could be converted to an unsigned int
// subtraction and compare for only a single branch
while (cp^ > #0) and (cp^ <= #32) do
Inc(cp);

// using null terminater for end of file
Result := cp^ <> #0;

if Result then
begin
FTokenStart := cp;
Inc(cp);
while cp^ > #32 do
Inc(cp);
end;

FCurrPos := cp;
end;

关于delphi - 在 Delphi 中解析一行的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/287789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com