Search code examples
arrayswcflistmfcmanaged-c++

Fastest conversion of MFC CArray<int> to List<int> in Managed C++


We are currently in the process of changing a lot of code as we move from a 'single system' application to one that can farm out tasks to distributed processing nodes. The existing code is in a mix of unmanaged and now managed C++ code, but is also using C# code to provide a WCF interface between node and controller.

As a result of this move, a common code pattern I'm seeing which is likely to remain for the foreseeable future is a basic conversion of integer ID values from an MFC CArray to a managed List to enable serialisation over WCF. The current pattern is:

List<int>^ fixtures = gcnew List<int>(aFixtureIds.GetCount());

for(int i = 0; i < aFixtureIds.GetCount(); i++) //aFixtureIds is of MFC type CArray<int,int>
    {
        fixtures->Add(aFixtureIds[i]);
    }

We also use something similar in reverse, where if a List is returned we may convert it to a CIntArray for the calling function by iterating through it in a loop and calling Add.

I appreciate that the above doesn't look very intensive but it does get called a lot - is there a better pattern for performing this basic List<->CArray conversion that would use up less processing time? Is this the kind of code that can be optimised effectively by the compiler (I suspect not but am willing to be corrected)? List sizes vary but will typically be anything from 1 to tens of thousands of items, potentially more.


Solution

  • A few suggestions although a lot of it will depend on your application details:

    • Measure: I suppose it gets old that every SO question on performance has people just saying "measure first" but this is usually (always?) good advice, particularly in this case. I fear that you're drastically over estimating how much time such a conversion takes on a modern desktop computer. For example, on my pokey 4-year old desktop a quick test shows I can add 100 million integers to a CArray in just 250 ms. I would expect roughly the same performance in C# for the List. This means that your 10,000 element list would take around 25 microseconds to run. Now, obviously if you are doing this 1000s of times a second or for billions of elements it becomes an issue although the solution in these cases would not be a faster algorithm but a better one.
    • Update When Needed: Only update the arrays when you actually need the information. If you are updating frequently just because you 'might' need it you will likely be wasting conversions that are never used.
    • Synchronize Updates: Instead of updating the entire array at a time update the elements in both copies of lists at the same time.
    • Just Use One List: While it sounds like you can't do this at least consider just using one list instead of two copies of the same information. Hide the element access in a function/method/class so you don't need to know whether the data is stored in a CArray<> or a List<>.
    • Better Design/Algorithm: If you measure and you do find that a lot time is being spent in this conversion then you're probably going to get a far better return by improving the code design to reduce or eliminate the conversions needed. Off-hand, there's probably not a whole lot of improvement possible in just copying a CArray<> to a List<>.