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

convert array<uchar>^ to std::vector<char> data;

我正在使用托管和非托管代码,我需要转换 将 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]);
}

看起来好像可以,但是速度很慢。关于如何更快完成的任何想法?

您可以做的第一个优化是 reserve 向量中所需的 space,这样它就不必在向其中插入数据时自行调整大小.

这很简单:

data.reserve(tam);

这会提高性能,但不会提高那么多。你可以做得更好,你可以使用 memcpy,如 cppreference says:

std::memcpy is the fastest library routine for memory-to-memory copy.

所以让我们使用它。

首先,您需要 resize(不是 reserve)向量,以便它知道使用的字节数。然后,您可以使用 data() 函数获取指向其保存的原始数据的指针。

至于数组,它是一个托管对象,这意味着您需要 固定 它以便 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