What is the most efficient way to convert a std::vector<T> to a .NET List<U>?

≯℡__Kan透↙ 提交于 2020-07-05 02:39:09

问题


What is the most efficient way to convert a std::vector to a .NET List?

To give some context, I am wrapping an unmanaged C++ class with C++/CLI. The C++/CLI class holds a pointer to the C++ class and I have a wrapper for each public method.

One method returns a std::vector, so in my wrapper I was going to return the .NET class List. I.e.

// unmanaged class
class A
{
    public:
        std::vector<int> runList();
}

// managed class
public ref class A
{
    public:
        // the below is obviously extremely inefficient
        List<UInt32> MethodA()
        {
            std::vector<unsigned int> runList = mpChannelNode->runList();
            std::vector<unsigned int>::iterator itr;

            List<UInt32> list = gcnew List<UInt32>();

            for (itr = runList.begin(); itr != runList.end(); itr++)
            {
                list.Add(*itr);
            }

            return list;
        }

    private:
        A* mpChannelNode;
}

How can I make this more efficient? Feel free to recommend a different return type for the .NET class. Lets assume I just need to get that vector into managed world efficiently in any shape or form.


回答1:


If you're really that concerned about it, use unverifiable code instead:

List<unsigned>^ MethodA()
{
    std::vector<unsigned> const& runList = mpChannelNode->runList();
    array<unsigned>^ ret = gcnew array<unsigned>(runList.size());
    if (runList.size())
    {
        pin_ptr<unsigned> dest = &ret[0];
        std::memcpy(dest, &runList[0], runList.size() * sizeof(unsigned));
    }
    return gcnew List<unsigned>(ret);
}

That said, I'd be surprised if there was a noticeable difference either way...




回答2:


I am not familiar with C++-CLI but one small improvement you can make is to create your list with the right capacity from the beginning.

List<UInt32> list = gcnew List<UInt32>(runList.size());

Another improvement would be to pre-increment your C++ iterator instead of post-incrementing it because currently you create an extra object for every element that is discarded immediately.




回答3:


Consider turning into the vector directly into an array .. the below will work and be valid, until you resize the vector.

vector vec(10); int *array = &vec[0];

Then, you should be able to treat that (I think -- VS not on machine) as a passed array to populate your list.

You should also create your list with a size that you expect to need -- adding one by one will be slow.



来源:https://stackoverflow.com/questions/6146701/what-is-the-most-efficient-way-to-convert-a-stdvectort-to-a-net-listu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!