我一直在阅读虚拟方法及其调用方法。正如here和here所讨论的那样,我得出结论,他们不应该真的那么不同。
C#编译器发出IL代码,该代码通过call
IL指令调用静态方法,并通过callvirt
调用虚拟/非虚拟成员。似乎JIT的工作是要实际确定调用方法的对象实际上是否为null。所以两者的检查都是一样的。
此外,正如第一篇文章中所讨论的那样,在方法定义中保存元数据的vtable或表似乎在编译时被展平。换句话说,表格包含对象应该调用的方法,而不需要对继承链进行递归搜索。
综上所述,为什么虚拟方法被认为更慢?可能是一个间接(如果有的话)的一个层次的交易?请解释......
答案 0 :(得分:1)
确定要执行的实际方法实现将具有一些成本,而不仅仅是知道。这个成本可能非常小,并且很可能成本对于任何特定的上下文来说完全可以忽略不计,因为它实际上并不需要 。但成本并非为零,因此在特别对性能敏感的应用程序中,它会产生某些差异。
答案 1 :(得分:1)
您正在研究函数调用指令与直接寻址和间接寻址之间的区别。但是,间接函数调用的大部分“成本”不是调用本身,而是丢失了执行需要静态了解目标的优化的机会。内联,跨过程别名分析等。