代码之家  ›  专栏  ›  技术社区  ›  Niklas Winde

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

  •  14
  • Niklas Winde  · 技术社区  · 18 年前

    我有一个程序,有很多

    i := i +1;
    

    我认为

     inc(i);
    

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

    编辑:我对性能进行了一些测量,发现差异很小,实际上只有5.1222741794670901427682121946224e-8!所以这真的不重要。优化选项实际上并没有改变结果。感谢所有的提示和建议!

    6 回复  |  直到 18 年前
        1
  •  7
  •   Burkhard    18 年前

    如果 溢出检查 已打开。基本上 股份有限公司 不 进行溢出检查 .按照建议操作,并在打开这些编译器选项时使用反汇编窗口查看差异(每个选项都不同)。

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

        2
  •  17
  •   Jim McKeeth    18 年前

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

    用你喜欢的任何一种。

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

        3
  •  6
  •   community wiki PatrickvL    18 年前

    这一切都取决于“i”的类型。在Delphi中,通常将循环变量声明为“i:Integer”,但它也可以是“i:PChar”,在Delphi 2009和FPC(我猜在这里)以下的所有版本上解析为PAnsiChar,在Delphi2009和Delphi上解析为PWideChar。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_CHEKS和RANGE_CHECKS可能会影响最终结果,因此您应该注意根据自己的喜好进行设置。

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

        4
  •  3
  •   Ondrej Kelle    18 年前

    您可以在调试时在CPU窗口中验证它。对于这两种情况,生成的CPU指令是相同的。

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

    更正:我刚在Inc的文档中找到这个:

    “在某些平台上,Inc可能会产生 优化的代码,尤其适用于 紧环。"

    因此,坚持股份有限公司可能是明智的。

        5
  •  1
  •   robsoft    18 年前

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

    一般来说,我会使用inc(I),只要它显然只被用作某种类型的循环/索引,就使用+1,只要1会使代码更容易维护(即,将来可能会更改为另一个整数),或者从算法/规范的角度来看更具可读性。

        6
  •  0
  •   Samir    18 年前

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