Каков наиболее эффективный способ преобразования std :: vector <T>в список .NET <U>? - PullRequest
10 голосов
/ 27 мая 2011

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

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

Один метод возвращает 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.Предположим, мне просто нужно эффективно перенести этот вектор в управляемый мир в любой форме.

Ответы [ 3 ]

8 голосов
/ 27 мая 2011

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

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

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

3 голосов
/ 27 мая 2011

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

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

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

1 голос
/ 27 мая 2011

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...