可以内联虚拟 C# 成员吗?

Can virtual C# members be inlined?

考虑以下派生的替代实现,内部 类 旨在覆盖,返回 true:

public virtual bool IsInternal => false;

...和...

public virtual bool IsInternal() => false;

在内存和性能方面有什么区别?

编译器能否检测静态结果,并在 optimizing/inlining 时使用它们而不是为每个实例保存 属性 值或调用函数? 这些虚拟成员是否可以被编译器内联,会有什么影响?

What is the difference memory- and performance-wise?

None,它们都编译为虚拟方法(C# 属性只是 getter+setter 方法的不同语法)。

每个虚拟成员都会增加一个类型的 vtable 大小(不过这可以忽略不计,因为 vtable 是按类型而不是按实例的)。

在性能方面,虚拟调用是一些更昂贵的指令,并且还需要更多的内存访问,但是一个很好的 CPU,现代分支预测和大型缓存可以最大限度地减少影响。如果你真的关心那个级别的性能,你无论如何都不会使用 CLR - 就大多数开发人员应该关心的而言 virtual 调用成本与非虚拟调用相同。

Can the compiler detect the static results and, when optimizing/inlining, use them instead of saving the property value for each instance or invoking the function?

  • .NET Framework 1.0、1.1、2.0 和 4.0 中的 CLR 没有(据我所知)。 C# 编译器 可能 在某些微不足道的情况下(例如 (new BaseVirtualType().VirtualMethod()))用编译后的 CIL 中的非虚拟调用替换虚拟调用,但 JIT 不会进行优化(但 JIT 可能会内联它 ,但我不确定)。启用优化后,C# 编译器也可能内联。

  • 根据 .NET Core 3.0 的规范文档(见下文),.NET Core 2.0 中的 CLR 一些 去虚拟化。

  • .NET Core 3.0 中的 CLR 将更加激进,继承人规范文档如下:https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/GuardedDevirtualization.md