2010-05-25 4 views
6

C++과 달리 가상 및 일반적인 메서드를 결합 할 수 있습니다. 예를 들어 표준 vtbl 접근이 메서드 호출을 해결하는 데 사용할 수처럼 Generic<T> 버전의 수를 인스턴스화 할 수있는 점을 감안제네릭을 사용한 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>(); 
    } 
} 

, 그것은 보이지 않는, 사실 그렇지 않다. 생성 된 코드는 다음과 같습니다.

 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] 

여분의 코드는 generic 매개 변수에 따라 동적 vtbl을 찾은 다음 호출합니다. 이 구현의 세부 사항에 대해 작성한 사람이 있습니까? 비 제네릭 경우에 비해 얼마나 잘 수행됩니까?

답변

3

.NET generics 구현은 이러한 시나리오를 매우 쉽게 처리 할 수 ​​있습니다. 나는 얼마 전 그것에 대해 blog post을 썼다.

CLR이 제네릭을 구현하는 방법에 대한 정보를 찾는 데 가장 유용한 리소스 중 하나는 Micosoft Research의 paper입니다.

vtable에 대한 권리가 있습니다. JIT 컴파일러가 걸리면 CLR이 제네릭 형식의 실행 코드를 만드는 방식은 제네릭 형식 매개 변수에 따라 다릅니다. 처리는 값 유형과 참조 유형에 따라 다릅니다.

참조 형식 인 모든 제네릭 형식 매개 변수에 대한 실행 가능 코드 (인스턴스화, 기본 이미지)가 공유되는 동안 인스턴스화의 인스턴스 (개체)와 연결된 vtable은 구체적인 매개 변수 유형에 고유합니다.

여기서 상술 한 논문에서 관련 인용의 다음 CLR의 가비지 수집 힙

4.2 객체 표현 오브젝트, 오브젝트의 내용 (예를 들어 인터넷 필드들 또는 배열 뒤에 VTABLE 포인터 로 표시 있다 집단). vtable의 주요 역할은 가상 메소드 디스패치입니다. 정의 된 각 메소드에 대해 코드 포인터 을 포함하거나 객체 클래스에서 을 상속합니다. 그러나 단순한 클래스 유형의 경우 은 최소한 이고, vtable과 클래스 사이에 일대일 대응이있는 경우 객체 유형을 나타내는 에도 사용할 수 있습니다. 이 방식으로 vtable을 사용할 경우 유형의 유형 핸들이라고합니다.전체 전문화에 기반 다형성의 구현, 정확한 실행시의 형태의 개념 에서 같은 파라미터 화 된 형태의 무료 등 다양한 인스턴스 생성을 위해 오는 다른 vtable을 수 있습니다. 하지만 코드가 인 경우 List<string>List<object>과 같이 서로 다른 코드가 공유되어 있다고 가정합니다. 두 개의 인스턴스화에 대한 vtable은 과 동일하므로 런타임에 이라는 인스턴스를 나타내는 방법이 필요합니다.

는 ...

[각 인스턴스화 우리]는 vtable- 결합 앤 인스턴스화 구조에 대한 포인터에 의해 VTABLE 포인터를 장착하고 실체화 당 함 [구조] 중복.

+0

정확히 내가 뭘 찾고 있었는지 고마워! – zildjohn01

0

.NET 제네릭이 구현되는 방식에 따라 일반 클래스 (또는 메서드)를 사용할 때마다 CLR은 제네릭 매개 변수가 채워진 해당 클래스 (또는 메서드)의 새 구현을 만듭니다. 참조 유형의 경우 모두 단일 구현을 공유하십시오 (모두 같은 크기의 포인터 일뿐입니다). 구조체마다 크기가 다르기 때문에 각각 자체적으로 구현됩니다.

그래서 제네릭 형식/메서드의 각 구현에는 자체 vtable이 있고 해당 코드는 'lookup generic implementation'을 수행 한 다음 발견 된 구현에서 'lookup vtable override'를 수행하고 있다고 생각합니다.

관련 문제