【问题标题】:Is there any performance impact by using interface as reference使用接口作为参考是否有任何性能影响
【发布时间】:2024-05-03 20:55:02
【问题描述】:

在性能方面哪个更好:
1.)通过基类的引用引用一个对象

abstract class BaseClass{}

class A : BaseClass{}
class B : BaseClass{}

static void Main(){
 BaseClass objectInstance = new A();
           objectInstance = new B();
}


2.) 通过接口的引用引用对象:

 interface IBase{}

 class A : IBase{}
 class B : IBase{}

 static void Main(){
    IBase objectInstance = new A();
    objectInstance = new B();
}

【问题讨论】:

  • 这将是超级容易让你测试自己。与运行一个简单的基准测试相比,您可能需要更多时间来正确编写和格式化这个问题。
  • 这段代码没有任何后果,重要的是你接下来要做什么。接口方法调用确实有一些开销,它必须通过调用存根,并且抖动优化器不能内联该方法。性能差异很难准确测量,它是非常快的代码,并且通过使非接口方法完全消失来很容易弄乱基准。接口是一种结构化的设计模式,你既不能选择加入它们,也不能仅仅为了它而随意丢弃它们。由 CLR 进行了大量的微优化,它们并不糟糕。

标签: c# performance interface reference abstract-class


【解决方案1】:

影响是微观的,在您编写真正的性能关键部分代码之前,您可能不会注意并使用最适合您需求的任何内容。

但是,在一种情况下,您可能会遇到接口性能问题。当您有一个接受接口作为参数的方法并且您有一个实现该接口的结构时,就会发生这种情况。

class Demo {
    public static void Method(IInterface input) {};
}

struct Struct: IInterface {}


Demo.Method(new Struct(arg1, arg2))

这样的代码会导致结构体的装箱。您应该考虑使用带有约束的泛型以避免装箱

class Demo {
    public static void Method<T>(T input) where T: IInterface {};
}

【讨论】:

    【解决方案2】:

    可能存在时间/速度性能问题,但如果您使用的是小型集合,则差异可以忽略不计。如果您使用列表作为参数,请改用 iList..这取决于您。这是一个参考...https://github.com/dotnet/coreclr/issues/9105

    【讨论】:

      最近更新 更多