繁体   English   中英

C#方法多态性与泛型的性能

[英]Performance of C# method polymorphism with generics

我注意到在C#中,与C ++不同,您可以组合虚拟和通用方法。 例如:

using System.Diagnostics;

class Base {
    public virtual void Concrete() {Debug.WriteLine("base concrete");}
    public virtual void Generic<T>() {Debug.WriteLine("base generic");}
}

class Derived : Base {
    public override void Concrete() {Debug.WriteLine("derived concrete");}
    public override void Generic<T>() {Debug.WriteLine("derived generic");}
}

class App {
    static void Main() {
        Base x = new Derived();
        x.Concrete();
        x.Generic<PerformanceCounter>();
    }
}

鉴于可以实例化任何数量的Generic<T>版本,看起来不像标准的vtbl方法可用于解析方法调用,事实上它并非如此。 这是生成的代码:

        x.Concrete();
mov         ecx,dword ptr [ebp-8] 
mov         eax,dword ptr [ecx] 
call        dword ptr [eax+38h] 
        x.Generic<PerformanceCounter>();
push        989A38h 
mov         ecx,dword ptr [ebp-8] 
mov         edx,989914h 
call        76A874F1 
mov         dword ptr [ebp-4],eax 
mov         ecx,dword ptr [ebp-8] 
call        dword ptr [ebp-4] 

额外的代码似乎是根据通用参数查找动态vtbl,然后调用它。 有没有人写过这个实现的具体细节? 与非通用案例相比,它的表现如何?

.NET泛型实现可以轻松地处理这样的场景并且具有非常好的性能。 我刚刚写了一篇关于它的博客文章

Micosoft Research撰写的这篇论文是查找有关CLR如何实现泛型的信息的最佳资源之一。

你有关于vtable的事情。 当JIT编译器偶然发生时,CLR如何为泛型类型创建可执行代码取决于泛型类型参数。 值类型和引用类型的处理方式不同。

虽然可执行代码(实例化,本机映像)在作为引用类型的所有泛型类型参数的实例化之间共享,但与实例化的实例(对象)相关联的vtable对于具体参数类型是唯一的。

以下是上述论文的相关引用:

4.2对象表示CLR的垃圾收集堆中的对象由vtable指针表示,后跟对象的内容(例如字段或数组元素)。 vtable的主要作用是虚方法调度:它包含由对象类定义或继承的每个方法的代码指针。 但是对于简单的类类型,至少在vtable和类之间存在一对一的对应关系时,它也可以用来表示对象的类型。 当以这种方式使用vtable时,我们将其称为类型的类型句柄。 在基于完全特化的多态的实现中,精确运行时类型的概念是免费的,因为相同参数化类型的不同实例具有不同的vtable。 但现在假设代码在不同的实例之间共享,例如List<string>List<object> 两个实例的vtable将是相同的,因此我们需要某种方式来表示运行时的实例化。

...

[对于每个实例化,我们]用指向组合的vtable和实例化结构的指针替换vtable指针,并在每个实例化时复制它[结构]。

实现.NET泛型的方式,对于泛型类(或方法)的每次使用,CLR都会创建该类(或方法)的新实现,并填充泛型参数。对于引用类型,它们共享一个实现(因为它们都只是相同大小的指针); 每个结构都有自己的实现,因为大小都不同。

所以我猜测泛型类型/方法的每个实现都有它自己的vtable,并且该代码正在执行'查找通用实现',然后在它找到的实现上执行'lookup vtable override'。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM