簡體   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