在Delphi中inc(i)和i:= i + 1之间是否存在性能差异?
我有很多的程序
i := i +1;
在里面,我认为
inc(i);
看起来好多了。是否存在性能差异,或者函数调用只是由编译器内联?我知道这对我的应用可能根本不重要,我只是很好奇。
编辑:我对性能进行了一些评估,发现差异很小,实际上只有5.1222741794670901427682121946224e-8!所以真的没关系。优化选项确实并没有太大改变结果。感谢我们提供的所有提示和建议!
解决方案
现代编译器会优化代码。
inc(i)和i:= i + 1;几乎一样。
使用任何我们喜欢的。
编辑:正如吉姆·麦基思(Jim McKeeth)所纠正的:与"溢出检查"(Overflow Checking)有区别。 Inc不进行范围检查。
我们可以在调试时在CPU窗口中对其进行验证。两种情况下生成的CPU指令都是相同的。
我同意Inc(I);
看起来更好,尽管这可能是主观的。
更正:我刚刚在Inc的文档中找到了这个:
"On some platforms, Inc may generate optimized code, especially useful in tight loops."
因此,建议我们坚持使用Inc.。
我们总是可以编写这两段代码(在单独的过程中),在代码中放置一个断点,然后在CPU窗口中比较汇编器。
通常,在显然仅用作某种循环/索引的地方,我会使用inc(i);而在1会使代码更易于维护的地方,我会使用+(1)未来),或者从算法/规范的角度更具可读性。
"在某些平台上,Inc可能会生成优化的代码,这在紧密循环中特别有用。"
对于诸如Delphi之类的优化编译器,它不在乎。那是关于旧的编译器(例如Turbo Pascal)
这完全取决于" 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;
正如其他评论家已经说过的:通过打开,很容易看到编译器对代码的处理方式:
Views > Debug Windows > CPU Windows > Disassembly
请注意,诸如OPTIMIZATION,OVERFLOW_CHECKS和RANGE_CHECKS之类的编译器选项可能会影响最终结果,因此应注意根据自己的喜好进行设置。
提示:在每个单元中,$ INCLUDE都会引导文件的编译器选项,这样,当.bdsproj或者.dproj受到某种程度的损坏时,我们就不会丢失设置。 (有关此示例,请查看JCL的源代码)
如果打开了"溢出检查",则会有很大的不同。基本上,Inc不执行溢出检查。按照建议的方法进行操作,并在打开那些编译器选项时使用反汇编窗口查看区别(每个区别都不同)。
如果关闭了这些选项,则没有任何区别。根据经验,当我们不关心范围检查失败时(因为我们不会遇到异常!),请使用Inc。