在Delphi中inc(i)和i:= i + 1之间是否存在性能差异?

Nik*_*nde 14 delphi performance

我有很多程序

i := i +1;
Run Code Online (Sandbox Code Playgroud)

在它和我想

 inc(i);
Run Code Online (Sandbox Code Playgroud)

看起来好多了.是否有性能差异或函数调用是否只是由编译器内联?我知道这可能与我的应用程序无关,我只是好奇.

编辑:我做了一些性能测量,发现差异非常小,实际上小到5.1222741794670901427682121946224e-8!所以真的没关系.优化选项确实没有改变结果.感谢所有提示和建议!

Jim*_*eth 17

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

如果关闭这些选项,则没有区别.经验法则,当您不关心范围检查失败时使用Inc(因为您不会得到例外!).


Bur*_*ard 7

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

使用您喜欢的任何一种.

编辑:正如吉姆麦克凯斯所纠正的那样:通过溢出检查,存在差异.Inc不进行范围检查.

  • 错误!打开范围检查或溢出检查并查看拆卸! (3认同)

Pat*_*kvL 6

这一切都取决于"我"的类型.在Delphi中,通常将循环变量声明为"i:Integer",但它也可以是"i:PChar",它解决了Delns 2009和FPC(我在这里猜测)以下的所有内容的PAnsiChar,以及PWideChar on 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;
Run Code Online (Sandbox Code Playgroud)

正如其他的anwsers已经说过的那样:通过开放可以很容易地看到编译器对你的代码做了什么:

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

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

关于这一点的提示:在每个单元中,$ INCLUDE控制编译器选项的文件,这样,当.bdsproj或.dproj以某种方式损坏时,您不会丢失设置.(查看JCL的源代码以获得一个很好的例子)