2009-10-21 6 views
0

문제 :사용 반사 스텁 대리자 필드를 초기화 유유히

  • 코드 생성기에 의해 생성 된 수천 위임 필드가 닷넷 2.0 클래스

    1. 다양한 서명
    2. 대리자는 값을 반환 할 수도 있고 반환하지 않을 수도 있습니다.
    3. 제네릭 없음
  • 이 대표 훨씬 런타임 지금 훨씬 비용 ~ 300ms를 초기화 대리인은 간단 초기화

    1. 하지만 비싼
    2. 에서 빠르게 초기화 - 허용하지만,
    3. 를 완벽하지 사용자는 해당 대표단의 10 % 미만을 사용합니다. 많이 위임자 만 지연로드 할 수있는 경우 더 빠릅니다!

      가 느리게 대리자 필드를 초기화하는 반사를 사용할 수 있습니다 :

문제를 (사용하지 않는 것에 대해 지불하지 않습니다)? 의사 코드에서 :

class Delegates 
{ 
    int FooDelegate(IntPtr p1, float* p2); 
    public static FooDelegate Foo; 
    // Several thousand more  
    ... 

    static Delegate LoadDelegate(string name, Type signature) 
    { 
     // complex and expensive p/invokes 
    } 

    static void SetupStubs() 
    { 
     // Create loader stubs (using reflection because 
     // JIT times are prohibitive when done inline) 
     foreach (FieldInfo f in typeof(Delegates) 
      .GetFields(BindingFlags.Static | BindingFlags.NonPublic)) 
     { 
      // We need to generate a compatible delegate, which: 
      // (a) calls LoadDelegate("Foo", typeof(FooDelegate)), and 
      // (b) assigns its result to the Foo field (replacing the stub), 
      // (c) executes Foo(p1, p2) and returns the result, where 
      // p1 and p2 are the original parameters specified by the user. 
      Delegate stub = ...; 
      f.SetValue(null, stub); 
     } 
    } 
} 

I는 는 (a), (b) 및 (c) 실행하는 스터브를 만들 가능하다는 느낌이 있지만, 어떻게 을 신성 관리하지.

이상적으로 코드는 .Net 2.0 및 Mono 2.0을 실행해야하며 이 아니어야합니다.은 System.Reflection.Emit을 사용해야합니다. 그러나 나는 또한 .Net 3.5 또는 DynamicMethod를 사용하는 솔루션에 관심이 있습니다.

아이디어가 있으십니까? :)

답변

1

예, 런타임에 스텁을 동적으로 생성 할 수는 있지만 300 밀리 초가 더 걸릴 가능성이 큽니다. 수천 개의 스텁을 생성하는 것에 대해 이야기하고 있습니다. 그리고 btw, DynamicMethod 또는 어쩌면 3.5식이 필요합니다.

가장 좋은 방법은 컴파일하기 전에 스텁을 생성하는 것입니다. 이상적으로, 필드를 생성하는 코드 생성기도 스텁을 생성해야합니다. 기존 코드 생성기를 수정할 수없는 경우 T4와 같은 템플릿 엔진을 사용할 수 있습니다.

+0

초기 테스트에서는 대표자 초기화시 JIT보다 반사가 훨씬 빠르다는 것을 보여주었습니다. JIT 코드의 경우 반사 ~ 300ms ~ 2500ms입니다. (코드가 JIT 된 후에는 분명히 테이블이 바뀌지 만 우리는 초기 시작 시간에만 관심이 있습니다.) 두 테스트 모두 동일한 LoadDelegate() 메서드를 사용했습니다. DynamicMethod 또는 표현식을 사용한다면이 스텁은 어떻게 생겼을까요? 어떻게 원래 매개 변수를 캡처하고 스텁 자체에서 메서드를 실행합니까? – BlackStar