C#中继承的性能考虑

11

如果我创建一个拥有public int I;(或任何其他字段)的类,和创建一个继承于一个拥有public int I; 的基类的类,编译器会生成相同的IL代码吗?

无论哪种方式得到的类表现都是一样的,但编译器是否也一样呢?

也就是说,编译器是将基类中的代码复制粘贴到派生类中,还是在继承时实际上创建了两个不同的类对象?

class A
{
    public int I;
}

class B : A
{
}

现在以下两种调用DoSomething()之间是否存在性能差异?

var a = new A();
var b = new B();
DoSomething(a.I);
DoSomething(b.I); // Is this line slower than the above line due to inheritance?

尝试忽略编译器可能为此特殊情况进行的任何优化。我的问题是关于C#中继承是否普遍存在性能惩罚的。大多数时候我并不关心,但有时我想要优化一段高频代码。


2
听起来你在试图过早进行优化? - jgauffin
4
看起来这是你可以轻松自行基准测试的东西。为什么你没有这样做? - Oded
1
jgauffin:请阅读我问题中的最后一句话 :) - Olhovsky
1
Oded: 有几个原因:像这样的基准测试很容易出错,现在有人观看SO问题可能已经心中有答案,共享这些信息以便于轻松地进行搜索是SE站点目的的一部分,并且我还不知道如何查看C# IL。 - Olhovsky
你是在询问调用的成本还是方法本身的性能? - Jon Skeet
显示剩余5条评论
1个回答

11

编译器发出的代码是相同的;事实上,即使在一个被密封类中调用非虚实例方法时,它也使用Callvirt——这与任何使用多态性调用方法时所使用的方式相同。

不是复制/粘贴——您在A中编写的代码仍然作为A的一部分存在。而且,因为继承并不会导致产生两个对象。它是组合了行为;一个B的实例同时拥有A的实现,但这并不是通过复制粘贴来实现的:一个B也是一个A——例如,一个Dog也是一个Mammal


等等,所以明确一下:如果我从基类继承一个方法,与在一个不继承任何类的密封类上调用一个方法,这些方法调用的性能也是相同的吗? - Olhovsky
2
在大多数可衡量的方面,是的;可能会有一些内联的细微差别,但不值得激动。哦,还有关于“不继承任何类”的问题 - 任何类都是从object继承的,而object则是一个类。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接