首页 > 解决方案 > 为什么重载 ++ 比仅增加值花费的时间要长得多?

问题描述

为什么将(在我的情况下)Uint 增加 100.000.000 次需要约 0.175 秒,而在结构中增加 Uint 相同的次数需要约 1.21 秒?

这些测试已经进行了大约 10 次,结果几乎相同。如果没有办法,那就这样吧。但我想知道是什么原因造成的。时间增加相当显着。下面的运算符重载是使用的确切代码:

private uint _num;        
public static Seq operator ++(Seq a)
{
    a._num++; return a;
}

我选择编辑实例本身(如果这违反准则)而不是返回一个新实例,因为这也需要相当长的时间。

这个结构会非常频繁地增加,因此我正在寻找增加处理时间的原因。

标签: c#operator-overloading

解决方案


这只是抖动有多聪明的问题。对于常规局部 int 变量,语句

x++;

在许多情况下可以简化为单个机器指令,因为可以注册局部变量。如果它没有被注册,那么指令序列将是加载值,递增它,然后存储它,所以是一些指令。

但是结构上的重载++具有以下语义。假设我们有我们的结构s并且我们说s++. 这意味着我们有效地实施

s = S.operator++(s);

那有什么作用?

  1. 复制 froms到作为新形式参数的局部变量位置
  2. 存储任何将被被调用者覆盖的寄存器状态
  3. 执行调用指令
  4. 加载形式的值,增加它,存储它
  5. 将新值复制到为返回值保留的位置
  6. 执行返回指令
  7. 恢复上一个激活帧的状态

  8. 将返回的值复制到s.

因此,您的快速程序正在执行第 4 步。您的慢速程序正在执行第 1 到第 8 步,并且慢了大约 8 倍。抖动可以确定这是内联的候选对象并消除其中一些成本,但这绝不是必需的,并且有很多原因可能会选择不内联。抖动不知道这个增量对你很重要。


推荐阅读