Каков наиболее эффективный способ преобразования std::vector <T> в .NET List <U>?

Каков наиболее эффективный способ преобразования std::vector в список .NET?

Чтобы дать некоторый контекст, я обматываю неуправляемый класс С++ с помощью С++/CLI. Класс С++/CLI содержит указатель на класс С++, и у меня есть оболочка для каждого публичного метода.

Один метод возвращает std::vector, поэтому в моей обертке я собираюсь вернуть список классов .NET. То есть.

// 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;
}

Как я могу сделать это более эффективным? Не стесняйтесь рекомендовать другой тип возврата для класса .NET. Предположим, мне просто нужно получить этот вектор в управляемом мире эффективно в любой форме или форме.

Ответ 1

Если вы действительно обеспокоены этим, используйте вместо этого непроверяемый код:

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);
}

Тем не менее, я был бы удивлен, если бы была заметная разница в любом случае...

Ответ 2

Я не знаком с С++ - CLI, но одно небольшое улучшение, которое вы можете сделать, это создать список с нужной емкостью с самого начала.

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

Еще одним преимуществом было бы предварительное увеличение вашего итератора на С++ вместо его последующего увеличения, поскольку в настоящее время вы создаете дополнительный объект для каждого элемента, который немедленно отбрасывается.

Ответ 3

Рассмотрим превращение в вектор непосредственно в массив. ниже будет работать и быть действительным, пока вы не измените размер вектора.

вектор vec (10); int * array = & vec [0];

Затем вы должны уметь рассматривать это (я думаю - VS не на машине) как переданный массив для заполнения вашего списка.

Вы также должны создать свой список с тем размером, который вы ожидаете, - добавление по одному будет медленным.