2013-06-30 3 views
0

C# 응용 프로그램에서 네이티브/비 관리 C++ DLL을 사용하고 있습니다. 이벤트가 발생하면PInvoke가 포함 된 콜백이 매우 느립니다.

[DllImport("MyHook.dll", CallingConvention = CallingConvention.Cdecl)] 
[return: MarshalAs(UnmanagedType.U1)] // necessary due to http://dotnet.dzone.com/articles/pinvoke-c-bool-return-values 
private static extern bool InstallHook(CallbackPrototype callback); 

private delegate int CallbackPrototype(byte* bytes, int size, int max); 

// ... 

var callback = new CallbackPrototype(MyCallback); 
_callbackHandle = GCHandle.Alloc(callback); 
var result = InstallHook(callback); 

// somewhere when I'm removing the hook, I call _callbackHandle.Free(); 

그런 다음, 네이티브 C++ DLL 내 콜백을 호출 나는의 PInvoke를 사용하여 C#에서 콜백 메소드를 등록하는 기본 함수를 호출합니다.

private int MyCallback(byte* bytes, int size, int max) 
{ 
    //var buffer = new byte[size]; // A 
    //Marshal.Copy(new IntPtr(bytes), buffer, 0, size); // B 

    //WrapperInstance.ParseBytes(buffer, 0, size); // C 
    var x = 1 + 1; // D 

    return size; 
} 

모든 것이 주석 처리되면 제대로 작동합니다. 콜백에서 라인 A의 주석 처리를 제거하면 속도가 느려집니다. 콜백이 중요한 순간에 호출되기 때문에 나는 그것을 알아 차린다. 콜백 런타임 기간이 너무 길어서 인간으로 인식하지 못하는 것은 용납되지 않습니다.

어떻게 될 수 있습니까? 크기는이며 매개 변수는 1에서 100 사이입니다. 할당해야 할 최대 100 바이트입니다. 오늘날 컴퓨터에는 거의 사용되지 않습니다. 콜백 런타임을 훨씬 빠르게 만드는 개선이 필요합니다. 어떤 아이디어?

테스트를 계속 진행하기 위해 D 행을 추가했습니다. 아무런 영향이 없습니다.

편집 : 자세한 테스트를 위해 클래스를 만들 때 큰 버퍼를 할당했습니다. 그래서 A 라인은 콜백에 더 이상 있지 않습니다. 그런 다음 B 행이 주석 처리되면 갑자기 엄청난 시간이 걸리기 시작합니다. 이것은 관리 코드/가상 머신과 관련이 있어야합니다. 빨리 할 수있는 가능성이 있기를 바랍니다.

+1

비용이 많이 드는 메소드 호출을 * 제거 *하여 코드 속도가 느려지는 것은 물론 완전히 직관적이지 않습니다. 분명히 시행 착오 접근법을 중단하고 프로파일 러를 사용하여 * evidence *를 수집해야합니다. –

+0

콜백이 엄청나게 많이 호출 될 수 있습니까? – ChaseMedallion

+0

약이라고합니다. 2 초에 한 번. 한스 패 자매, 내가 너를 제대로 이해하면 너는 뭔가를 오해한다. 내가 전화를 끊을 때 통화가 느려지 네. 내가 잘못했다면 미안해, 내 영어가별로 좋지 않아. 내 눈에 성능 문제가있을 때 왜 프로파일 러를 사용해야하는지 알 수 없습니다. –

답변

1

기본적으로 버퍼에서 바이트를 복사 한 다음 나중에 파싱하는 것입니다. ,

 var bytes = ReadBytes(address, Marshal.SizeOf(typeof(T)), isRelative); 

     fixed (byte* b = bytes) 
      return (T) Marshal.PtrToStructure(new IntPtr(b), typeof (T)); 

내가 내 기억 라이브러리에서이 예제를 촬영했습니다, 그리고 나는 그것이 꽤 빨리 당신이 지금 사용하고있는 코드보다있을거야라고 생각 : 당신은 너무 좋아, 한 번에 그렇게 할 수 값 유형 만 검색하려고한다고 가정합니다.