将数组<uchar> ^转换为std :: vector <char>数据;

时间:2016-06-15 15:00:07

标签: type-conversion c++-cli unmanaged managed

我正在使用托管和非托管代码,我需要转换 将array<uchar>^ image转换为std::vector<char> data

我开始这样做了:

array<uchar> ^image = gcnew array<uchar>(tam);
reader2->GetBytes(0, 0, image, 0, tam);

vector<uchar> data;
for (int idxImage = 0; idxImage < tam; idxImage++)
{
    data.push_back(image[idxImage]);
}

它看起来很有效,但速度很慢。关于如何更快地完成任何想法?

1 个答案:

答案 0 :(得分:2)

您可以做的第一个优化是保留向量中所需的空间,因此在向其中插入数据时不必自行调整大小。

这很简单:

data.reserve(tam);

这将提高性能,但不会那么多。你可以做得更好,你可以使用memcpycppreference says

  

std::memcpy是内存到内存复制的最快库例程。

所以让我们使用它。

首先,您需要调整(不是保留)向量,因此它知道使用的字节数。然后,您可以使用data()函数获取指向它所保存的原始数据的指针。

对于数组,它是一个托管对象,这意味着你需要 pin 它,所以GC不会移动它。在C ++ / CLI中,这是通过pin_ptr完成的。

总之,这是最终的代码:

data.resize(tam);
pin_ptr<uchar> pinned = &image[0];
std::memcpy(data.data(), pinned, tam);

我已经对它进行了测试,而且很多更快。这是一个完整的测试程序:

#include "stdafx.h"
#include <vector>

typedef unsigned char uchar;

void test1(array<uchar>^ image)
{
    std::vector<uchar> data;
    int tam = image->Length;

    auto sw = System::Diagnostics::Stopwatch::StartNew();

    for (int idxImage = 0; idxImage < tam; idxImage++)
    {
        data.push_back(image[idxImage]);
    }

    sw->Stop();
    System::Console::WriteLine("OP:      {0} ms", sw->ElapsedMilliseconds);
}

void test2(array<uchar>^ image)
{
    std::vector<uchar> data;
    int tam = image->Length;

    auto sw = System::Diagnostics::Stopwatch::StartNew();

    data.reserve(tam);
    for (int idxImage = 0; idxImage < tam; idxImage++)
    {
        data.push_back(image[idxImage]);
    }

    sw->Stop();
    System::Console::WriteLine("reserve: {0} ms", sw->ElapsedMilliseconds);
}

void test3(array<uchar>^ image)
{
    std::vector<uchar> data;
    int tam = image->Length;

    auto sw = System::Diagnostics::Stopwatch::StartNew();

    data.resize(tam);
    pin_ptr<uchar> pinned = &image[0];
    std::memcpy(data.data(), pinned, tam);

    sw->Stop();
    System::Console::WriteLine("memcpy:  {0} ms", sw->ElapsedMilliseconds);
}

int main(array<System::String ^> ^args)
{
    size_t tam = 20 * 1024 * 1024;
    array<uchar>^ image = gcnew array<uchar>(tam);
    (gcnew System::Random)->NextBytes(image);

    test1(image);
    test2(image);
    test3(image);

    return 0;
}

我的结果是:

OP:      123 ms
reserve: 95 ms
memcpy:  8 ms