2008-09-26 141 views
14

我有一个过程有很多的德尔福的inc(i)和i:= i + 1之间有性能差异吗?

i := i +1; 

,我认为

inc(i); 

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

编辑:我做了一些测量的性能,发现差别很小,实际上只有5.1222741794670901427682121946224e-8!所以这真的没关系。而优化选项并没有真正改变结果。感谢您的所有提示和建议!

+0

“5.1222741794670901427682121946224e-8”?? “5.12e-8”有什么问题? :-) 我想不出任何需要32位有效数字的实际应用,也没有任何测量甚至只有一半的数据是正确的。 “一位数学家希望pi达到10亿位,对于工程师pi等于3.14” – stevenvh 2009-02-15 18:09:14

+0

呵呵,那么我跑了一个测试,结果是所以我只是剪切和粘贴它,因此大量的数字:) – 2009-02-16 07:14:29

回答

7

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

使用任何你喜欢的。

编辑:正如吉姆McKeeth纠正:用溢出检查是有区别的。 Inc不做范围检查。

+3

错了!打开范围检查或溢出检查并查看反汇编! – 2008-09-27 07:41:37

3

可以在CPU窗口,可以验证它,而调试。两种情况下生成的CPU指令都是相同的。

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

更正:我刚刚发现这个对公司的文档中:

“在某些平台上,公司可能产生 优化的代码,在 紧密的循环特别有用。”

所以它可能是最好坚持公司

+0

Inc跳过范围检查 – 2008-09-27 18:09:29

1

你总是可以编写代码两件(在单独的程序),将断点在代码和比较在CPU窗口汇编。一般来说,我会使用inc(i),无论它明显只用作某种类型的循环/索引,还是+ 1,只要1使代码更容易维护(也就是说,它可能是可以改变的到未来的另一个整数),或者从算法/规范的角度来看更具可读性。

+0

不是inc(i,1),就像清除并容易更改为inc(i,2)一样? – Argalatyr 2008-09-27 05:03:30

0

“在某些平台上,公司可能生成优化的代码,在紧凑循环中特别有用。” 对于优化的编译器,如Delphi,它并不在意。为约旧编译器(例如Turbo Pascal的)

6

这完全取决于的“I”类型。在Delphi中,通常会将循环变量声明为“i:Integer”,但它也可以是“I:PChar”,它解决了Delphi 2009和FPC下面的所有问题(我在这里猜测)的PAnsiChar和PWideChar Delphi 2009和Delphi.NET(也猜测)。

自2009年德尔福可以做指针运算公司(我)也可以上键入三分球完成(如果它们与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; 

至于其他anwsers已经说了:这是relativly容易看到打开了一下编译器做你的代码:

视图>调试窗口> CPU的Windows > Disassembly

请注意,OPTIMIZATION,OVERFLOW_CHECKS和RANGE_CHECKS等编译器选项可能会影响最终结果,所以您可以d请注意根据您的喜好进行设置。

关于此问题的提示:在每个单元中,$ INCLUDE引导编译器选项的文件,这样,当您的.bdsproj或.dproj受到某种程度的损坏时,您不会松动设置。 (看看JCL的源代码就是一个很好的例子)

16

如果溢出检查处于打开状态,则会有很大差异。基本上公司做溢出检查。按照建议进行操作,并在打开这些编译器选项时使用反汇编窗口来查看差异(每种情况都不相同)。

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