Calling an unmanaged DLL from C# (for performance)

Posted on 2007-07-21
Last Modified: 2013-12-14
I have a situation in which I need to get a lot of system level data from the Win32 API. There is a .NET API made specifically for getting this data and it produces correct results. However, it is pretty slow. I needed to speed up the performance, so I wrote a lot of in unmanaged code in VC++. The bottom line is that when comparing the retrieval of data, and I have meticulously benchmarked it, the unmanaged code is 85% faster. In fact, the amount of data that will bet gather can range from 640KB to maybe a 100MB, and my 85% speedup is comparing the unmanaged code gathering the data AND writing it out, while the C# version merely reads it.

I've compared my C++ code to the Reflector output of the .NET API that is equivalent, and I think I know why the .NET implementation is so slow, but in any event I need to use this unmanaged code. The thing is, I'll be doing this retrieval from a .NET Windows Service.

What is the best way to call my unmanaged code from C# to get the best performance? Basically, I *ultimately* want to populate a .NET DataTable with this data. There can be anywhere from 400 - 100,000 rows of data and, again, 640KB-100MB of data. I guess the strategy is to reduce the amount of marshaling? (The C++ data is currently stored in a class but can be changed to a struct)

Anyway, what is the best way to do this to preserve performance? Doing a managed C++ DLL and then calling the Win32 code could be an option, though I've never used managed extensions for C++. But would that do much in the way of performance over calling the unamanged stuff from C#, since either way there its crossing the border between managed and unmanaged?

(Just to clarify, I know about P/Invoke. Its not a question of whether its possible to do this but what is the best method from a performance perspective.)
Question by:NetworkArchitek
    LVL 19

    Expert Comment

    Without knowing any details of what you are doing, I would not comment on any "best" way of doing something.  In general, however, you seem to understand the issues involved.  but to get a discussion going, I have these comments:

    1) Keep as little data as possible crossing the managed/unmanaged boundary.
    2) Keet the data crossing the boundary as simple as possible to avoid complex marshaling.
    3) Since you have been able to compare the Reflected .NET code against your C++ code, is there a way to write .NET code yourself that works around the performance limitations that you identified in the framework code?  I have used that technique with success.  Not really feasible if it's too far down in the .NET guts.
    4) You are dealing with a fairly big chunk of data.  What kind of timing are you looking at when you say the unmanaged code is 85% faster?  There's a good chance you lose that advantage marshaling multiple MB of data.
    LVL 10

    Author Comment

    Thanks for the reply. For #3, that's not really an option because for one, the .NET API is doing a lot of marshaling and I would have to recreate what I've done but still do a whole lot of Interop.

    For #4, in terms of timing, my unmanaged code runs (say for a larger dataset of about 10MB-20MB) it runs in several seconds (say 10-15 seconds), while the .NET code takes a 1-2 minutes (even if you rerun the function again to dismiss the problem of JIT compilation). Also, I will ultimately do filtering on the data which will make my unmanaged code's performance be much better but the way the .NET API's method works, it will not get as much benefit from filtering.

    I think taking the output from the unmanaged, making it like a CSV and compressing it, then load it/decompress from C# would be faster than just letting C# do it through the .NET API (basically, the .NET API makes a *lot* of unnecessary calls to LoadLibraryEx() which is a primary reason why it is soooo slow). However, I don't want to go that route.
    LVL 19

    Accepted Solution

    What do you intend to do with the .NET DataTable?  Is it reasonable to just do that whole part of your app in unmanaged code and forget .NET?  Then you can just do a simple PInvoke call to execute that functionality and not have to worry about marchaling all the data back to managed space.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Highfive + Dolby Voice = No More Audio Complaints!

    Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

    For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK ( for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
    A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
    This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
    The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.

    737 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    16 Experts available now in Live!

    Get 1:1 Help Now