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