Delphi 中 inc(i) 和 i := i + 1 之间有性能差异吗?

问题描述 投票:0回答:6

我有一个包含很多

的程序
i := i +1;

在其中,我认为

 inc(i);

看起来好多了。是否存在性能差异,或者函数调用是否只是由编译器内联?我知道这对我的应用程序来说可能根本不重要,我只是好奇。

编辑:我对性能进行了一些测量,发现差异非常小,实际上小到 5.1222741794670901427682121946224e-8!所以这真的没关系。优化选项确实没有对结果产生太大影响。感谢您的所有提示和建议!

performance delphi
6个回答
18
投票

如果打开溢出检查,会有很大的差异。基本上Inc进行溢出检查。按照建议进行操作,并使用反汇编窗口查看打开这些编译器选项时的差异(每个选项都不同)。

如果关闭这些选项,则没有区别。根据经验,当您不关心范围检查失败时,请使用 Inc(因为您不会遇到异常!)。


7
投票

现代编译器优化代码。
inc(i) 和 i:= i+1;几乎一样。

使用您喜欢的任何一个。

编辑:正如 Jim McKeeth 纠正的那样:溢出检查是有区别的。 Inc 不进行范围检查。


6
投票

这一切都取决于

i
的类型。在 Delphi 编程语言中,通常将循环变量声明为
i: Integer
,但也可以是
i: PChar
,在 Delphi 2009 和 FPC 以下的所有内容上解析为
PAnsiChar
(我在这里猜测),并解析为
 PWideChar
关于 Delphi 2009 和 Delphi.NET(也是猜测)。

由于 Delphi 2009 可以进行指针数学运算,因此

Inc(i)
也可以在类型化指针上完成(如果它们是在打开
POINTER_MATH
的情况下定义的)。

例如:

type
  PSomeRecord = ^RSomeRecord;
  RSomeRecord = record
    Value1: Integer;
    Value2: Double;
  end;

var
  i: PSomeRecord; 

procedure Test;
begin
  Inc(i); // This line increases i with SizeOf(RSomeRecord) bytes, thanks to POINTER_MATH !
end;

正如其他答案已经说过的:通过打开以下内容,可以相对容易地查看编译器对代码的构成:

视图 > 调试窗口 > CPU 窗口 > 反汇编

请注意,OPTIMIZATION、OVERFLOW_CHECKS 和 RANGE_CHECKS 等编译器选项可能会影响最终结果,因此您应该根据自己的喜好进行设置。

对此的提示:在每个单元中, $INCLUDE 都有一个控制编译器选项的文件,这样,当您的

.bdsproj
.dproj
因某种原因损坏时,您就不会丢失设置。 (查看 JCL 的源代码以获得一个很好的示例)


3
投票

调试时可以在CPU窗口中进行验证。两种情况生成的 CPU 指令是相同的。

我同意

Inc(I);
看起来更好,尽管这可能是主观的。

更正:我刚刚在 Inc 的文档中找到了这一点:

“在某些平台上,Inc 可能会生成 优化的代码,特别适用于 紧密的循环。”

所以建议坚持使用 Inc.


1
投票

您始终可以编写两段代码(在单独的过程中),在代码中放置断点并在 CPU 窗口中比较汇编程序。

一般来说,我会在任何明显仅用作某种循环/索引的地方使用 inc(i) ,并在 1 使代码更易于维护的地方使用 + 1 (即,可能可以更改为另一个整数将来)或者只是从算法/规范的角度更具可读性。


0
投票

“在某些平台上,Inc 可能会生成优化的代码,在紧密循环中特别有用。” 对于像 Delphi 这样的优化编译器来说,它并不关心。这是关于旧编译器(例如 Turbo Pascal)

© www.soinside.com 2019 - 2024. All rights reserved.