可以内联虚拟 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
考虑以下派生的替代实现,内部 类 旨在覆盖,返回 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