1

今日、私はベクトル要素へのアクセスがベクトルのサイズとともに遅くなるという問題に遭遇しました。自分のコードではないので投稿できませんので、ご容赦ください。できるだけ詳しく説明しようと思います。

コードの機能は次のとおりです。1。Datasetクラスは、ファイル名を含む.txtファイルを受け取ります。これらは、ロードする必要のある標準のpng画像を指しています。これはImage<T>クラスによって行われます。画像はとして読み込まれImage<unsigned char>、にプッシュバックされますstd::Vector。2.データのロードが完了した後。データセットを操作するために、データセット内のベクトルにアクセスできます。したがって、次のようになります。

Dataset d;
d.init("filenames_list.txt"); //Loads the images
for(int i=0; i< d.getDatavector().size(); i++){
  Image<unsigned char> current = d.getDatavector()[i];
  //Do work on current image here.
}

ここで、getDatavector()はを返しますstd::Vector<Image<unsigned char> >。画像は、幅、高さ、チャネル数の3つのintを保持し、さらにインターリーブされたデータを指すBoost共有ポインターを保持します。

小規模なテストランの場合、約150の画像を含むファイルのリストがあります。これでプログラムを実行すると正常に動作し、速度測定により次のことがわかります

Image<unsigned char> current = d.getDatavector()[i];

完了するまでに約10msかかります。ただし、1500枚の画像の完全なデータセットで作業したい場合、上記の行は完了するのに約500ミリ秒かかります。私はそれを修正するために多くの異なることを試みましたが、コードの一般的な構造とメモリによっていくらか制限されています。私が次のことをすると:

const std::Vector<Image<unsigned char> > data = d.getDatavector();

ループの前は非常に高速に実行されますが、すぐにメモリが不足します。

問題の説明がやや曖昧であることはわかっています。正確な解決策を望んでいませんが、どこを見ればよいかについてのヒントを期待しています。私は同様の問題を探しましたが、人々はベクトルと配列の一般的な速度にしか関心がないようです。私の問題は、ベクトルの長さとともに速度が低下することです!誰かがこの種の問題を見た場合、どんな提案も大歓迎です!

これまで、std :: vector :: iteratorを使用するか、(d.getDatavector()。data())をポインターとして使用して、コンテンツにアクセスしようとしました。速度を向上させるものは何もないようです。

4

4 に答える 4

5

その理由は、サイクルで値ごとにベクトルを返すためです。

getDatavector()返品するstd::Vector<Image<unsigned short> >&かどうかstd::Vector<Image<unsigned short> > const&を確認してくださいstd::Vector<Image<unsigned short> >

于 2012-11-14T21:59:02.837 に答える
5

の署名はgetDataVector()どのように見えますか?それは...ですか

std::vector<Image<unsigned char>> getDataVector();

その場合、関数はby値を返し、のコピーをvector作成するたびに、要素がからコピーされ、それ自体が破棄されます。d.getDatavector()[i]vectorivectorvector

Datasetクラスを変更できる場合は、関数を次のように変更します

std::vector<Image<unsigned char>> const& getDataVector();

これで、関数が呼び出されるたびにコピーが作成されるわけではありません。

クラスを変更できない場合は、ループに入るに1つのコピーを作成してから、ループ内でローカル変数を使用してください。

std::vector基になるデータ配列は連続している必要があるため、問題がインデックス付けになることは不可能です。したがって、 i番目iの要素へのアクセスは、データ配列の開始アドレスをマークするポインターに追加し、結果を逆参照するのと同じくらい簡単です。

于 2012-11-14T22:03:02.790 に答える
2

C ++ 11、または以前のC ++を使用していますか?

以前のC++11で、getDataVectorがベクトルを返す場合は、コピーする必要がある場合があります。C ++ 11を使用している場合は、コピーせずに戻り変数に移動できます

それがあなたの減速の原因となる可能性があります。

ベクトルの要素へのアクセスは、定数時間の操作です。

于 2012-11-14T21:57:18.653 に答える
1

すでに述べたように、問題の根本はgetDatavector()ベクトルの完全なコピーを返すことにあるようであり、解決策は参照(または代わりにポインター)を返すことです。また、画像のコピーが作成されている場所で
も同様の問題が発生します。 これらの問題の1つの解決策は、次のように画像への直接アクセスを使用することです。Image<unsigned char> current = ...

Image<unsigned char>* getImage(int idx)
{
 if (idx < _myVector.size())
 {
   return &_myVector[idx].Image;
 }
 return NULL;
}

編集:参照を返すバージョン

    Image<unsigned char>& getImage(int idx)
    {
     if (idx < _myVector.size())
     {
       return _myVector[idx].Image;
     }
     // throw exception here;
    }

各画像のコピーが必要な場合は、明らかにこれは機能しません。

于 2012-11-14T22:18:14.443 に答える