2016-06-15 1 views
1

Je travaille avec le code managé et non managé et j'ai besoin de convertir convertir array<uchar>^ image en std::vector<char> data.convertir tableau <uchar>^en std :: vecteur <char> données;

J'ai commencé à le faire:

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

On dirait qu'il fonctionne, mais il est très lent. Une idée sur comment peut-on faire plus vite?

+0

Est-ce une réponse oui/non vous suffise? Ou cherchez-vous "Si oui, pouvez-vous me montrer comment?"? –

+0

Je recherche: "Si oui, pouvez-vous me montrer comment?" – user1705996

+0

Vous devriez montrer ce que vous avez essayé et où vous êtes coincé. Vous êtes plus susceptible d'obtenir de l'aide si vous avez montré une tentative honnête que de simplement demander le code de travail. –

Répondre

2

Une première optimisation que vous pouvez faire est réserve l'espace nécessaire dans le vecteur, de sorte qu'il ne doit pas se redimensionner lorsque vous insérez des données dans le vecteur.

C'est aussi facile que:

data.reserve(tam); 

Cela permettra d'améliorer les performances, mais pas par beaucoup. Vous pouvez faire mieux, vous pouvez utiliser memcpy, qui, comme cppreference says:

std::memcpy est la routine de la bibliothèque la plus rapide pour la copie de mémoire à mémoire.

Alors, utilisons cela.

Tout d'abord, vous devez redimensionner (non réserve) le vecteur, il connaît le nombre d'octets utilisés. Ensuite, vous pouvez obtenir un pointeur vers les données brutes qu'il détient avec la fonction data().

Comme pour le tableau, c'est un objet géré, ce qui signifie que vous devez épingler afin que le GC ne le déplace pas. En C++/CLI cela est fait avec pin_ptr.

Ensemble, voici le code final:

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

Je l'ai testé, et il est beaucoup plus plus vite. Voici un programme de test complet:

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

Mes résultats sont les suivants:

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

Impressionnant :). Je vous remercie!! – user1705996