2016-06-15 8 views
1

Я работаю с управляемым и неуправляемым кодом, и мне нужно преобразовать конвертировать array<uchar>^ image в std::vector<char> data.convert array <uchar>^to std :: vector <char> данные;

Я начал делать это:

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

Похоже, он работает, но очень медленно. Любая идея о том, как можно сделать быстрее?

+0

Будет Да/Нет ответа достаточно для вас? Или вы ищете «Если да, можете ли вы показать мне, как?»? –

+0

Я ищу: «Если да, можете ли вы показать мне, как?» – user1705996

+0

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

ответ

2

Первой оптимизацией, которую вы могли бы сделать, является резерв необходимое пространство в векторе, поэтому он не должен изменять размер, когда вы вставляете в него данные.

Это так же просто, как:

data.reserve(tam); 

Это позволит повысить производительность, но не так много. Вы можете сделать лучше, вы могли бы использовать memcpy, который, как cppreference 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 
+0

Awesome :). Спасибо!! – user1705996

 Смежные вопросы

  • Нет связанных вопросов^_^