什么是更快的C#,if语句,或虚函数调用函数什么都不做?为什么?

时间:2016-09-11 14:39:25

标签: c# performance if-statement virtual-functions

假设您有一个名为MyClass的类,它具有使用引用(myBehavior)封装到另一个名为Behavior的类的某种行为。默认情况下,MyClass应该没有行为。

对于在初始化之后未将myBehavior设置为任何内容的实例 - 如果myBehavior初始化为null,并且每次需要检查时,它是否会更加快速有效使用if(myBehavior)或者如果它被初始化为NullBehavior的实例,从Behavior派生,它会更快,它什么都不做?为什么?

class MyClass
{
   Behavior myBehavior = null;

   void doSomething()
   {
      if(myBehavior)
      {
         myBehavior.performAction();
      }
   }
}

或:

class NullBehavior : Behavior
{
   override void performAction()
   {
      // don't do anything
   }
}

class MyClass
{
   Behavior myBehavior = new NullBehavior(); // or equals some static universal instance of NullBehavior

   void doSomething()
   {
      myBehavior.performAction();
   }
}

1 个答案:

答案 0 :(得分:3)

让我们想象一下ASM代码会发生什么(IL之后):

  • 使用if包装它会产生额外的mov + cmp + jnz指令。

  • 调用函数将执行影响callstack维护(保存和恢复)的callret调用。它可能会产生类似:call ...然后push ebp mov ebp, esp ... pop ebp ret来保存它,然后再用额外的代码来恢复它。

if相比,显然调用函数会消耗更多的CPU操作。但另一方面,如果您的呼叫功能每次都会被调用(通常设置为myBehavior),那么我们就会在jnz / if上浪费额外的操作。

因此,如果您可以预测myBehaviour最有可能被设置(非null / NullBehavior),那么您应该选择第二个选项而不需要额外的if,但如果它更可能是null if然后值得用arr.push(arr[0]); 包装它。

相关问题