为什么Sysutils.RenameFile内联?

WeG*_*ars 12 delphi inline

[dcc32提示] H2443内联函数'RenameFile'尚未展开,因为在USES列表中未指定单位'Winapi.Windows'

我知道内联函数可以使代码更快.但我只看到了紧张的地方.例如,在一个大循环中调用一个小函数.

但如何内联IO功能可以提高速度?我的意思是通过内联RenameFile你可以获得几微秒.但是如果磁盘忙,执行函数本身可能需要几毫秒,甚至几十毫秒.

更重要的是,如果您使用的是RenameFile,那么您可能正处于执行其他I/O操作的代码块中.因此,这段代码将花费大量时间.所以,现在的收益更加微不足道.

Joh*_*ica 18

RenameFile 内联是因为它是对另一个函数的简单调用.

这是它的样子:

function RenameFile(const OldName, NewName: string): Boolean;
{$IFDEF MSWINDOWS}
begin
  Result := MoveFile(PChar(OldName), PChar(NewName));
end;
Run Code Online (Sandbox Code Playgroud)

通过内联此函数,调用将SysUtils.RenameFile被调用替换WinApi.Windows.MoveFile.

这具有以下优点:

  • 您保存一个电话,而不是两个电话,您只有一个电话.
  • 您的呼叫代码大小完全相同.
  • CPU保留一个用于分支预测的返回地址列表(返回堆栈缓冲区); 通过消除冗余调用,它可以节省此缓冲区中的空间,这可以防止在调用堆栈过深时出现错误预测.
  • 生成的代码较小,因为RenameFile它本身被消除了.

因此内联非常值得麻烦,特别是在递归代码中,调用堆栈可能会变深,CPU将开始错误预测返回,因为返回堆栈缓冲区溢出(一些CPU只有8个条目,顶部的CPU有24个条目).

通常,应该始终内联简单地调用另一个例程的每个例程.

正确预测的回报会花费一个周期,错误预测会耗尽管道并花费25个周期或更多周期; 因为需要从内存而不是缓冲区中获取返回地址,所以会添加更多延迟.

你是对的,这些优点在磁盘IO代码中都不重要,但这并没有减损像这样的简单重定向函数应该总是内联的事实.