我有一个包含很多
的程序i := i +1;
在其中,我认为
inc(i);
看起来好多了。是否存在性能差异,或者函数调用是否只是由编译器内联?我知道这对我的应用程序来说可能根本不重要,我只是好奇。
编辑:我对性能进行了一些测量,发现差异非常小,实际上小到 5.1222741794670901427682121946224e-8!所以这真的没关系。优化选项确实没有对结果产生太大影响。感谢您的所有提示和建议!
如果打开溢出检查,会有很大的差异。基本上Inc不进行溢出检查。按照建议进行操作,并使用反汇编窗口查看打开这些编译器选项时的差异(每个选项都不同)。
如果关闭这些选项,则没有区别。根据经验,当您不关心范围检查失败时,请使用 Inc(因为您不会遇到异常!)。
现代编译器优化代码。
inc(i) 和 i:= i+1;几乎一样。
使用您喜欢的任何一个。
编辑:正如 Jim McKeeth 纠正的那样:溢出检查是有区别的。 Inc 不进行范围检查。
这一切都取决于
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 的源代码以获得一个很好的示例)
调试时可以在CPU窗口中进行验证。两种情况生成的 CPU 指令是相同的。
我同意
Inc(I);
看起来更好,尽管这可能是主观的。
更正:我刚刚在 Inc 的文档中找到了这一点:
“在某些平台上,Inc 可能会生成 优化的代码,特别适用于 紧密的循环。”
所以建议坚持使用 Inc.
您始终可以编写两段代码(在单独的过程中),在代码中放置断点并在 CPU 窗口中比较汇编程序。
一般来说,我会在任何明显仅用作某种循环/索引的地方使用 inc(i) ,并在 1 使代码更易于维护的地方使用 + 1 (即,可能可以更改为另一个整数将来)或者只是从算法/规范的角度更具可读性。
“在某些平台上,Inc 可能会生成优化的代码,在紧密循环中特别有用。” 对于像 Delphi 这样的优化编译器来说,它并不关心。这是关于旧编译器(例如 Turbo Pascal)