3

3D ベクトルの各要素に対してメソッドを実行する最速の方法を知りたいです。

次があるとします。

std::vector<vector<vector<CLS>>> myVec;

可能な限り最速の方法で次のループを実行したい:

 for(int cycle=0;cycle<10;cycle++) // do it 10 times
 {
    for(int i=0;i<myVec.size();i++)
    {
       for(int j=0;j<myVec[i][constant].size();j++)
       {
           foo(myVec[i][constant][j]);
       }

    } 
 }

私の場合、中期指数は常に一定であることはよく言及されています。std::vector を十分に高速に使用していますか、それとも別のタイプのコンテナを提案していますか?

あなたの助けを楽しみにしています.Thanks

4

4 に答える 4

2

以下の方が高速です。

for(int i=0, int vecSize = myVec.size();i<vecSize;i++)
{
   for(int j=0, int currentLineSize = myVec[i][constant].size();j<currentLineSize;j++)
   {
       foo(myVec[i][constant][j]);
       //copy-paste this 10 times instead of having the outer loop
   }
} 

サイズについて何か知っている場合は、さらに展開を実行できます。

于 2012-10-03T14:03:21.523 に答える
2

イテレータの使用は高速化する必要があります (を呼び出すたびに配列全体を検索する必要はありませんfoo)。

typedef std::vector<CLS> v1;
typedef std::vector<v1> v2;
typedef std::vector<v2> v3;

for(int cycle=0;cycle<10;cycle++) // do it 10 times
{
    for(v3::const_iterator itOuter = myVec.begin(); itOuter != myVec.end(); ++itOuter)
    {
        const v1& vec = (*itOuter)[constant];
        for(v1::const_iterator itInner = vec.begin(); itInner != vec.end(); ++itInner)
            foo(*itInner);
    }
}

ただし、私はそれを測定しませんでした(コンパイルしようとさえしなかったので、タイプミスを許してください)

于 2012-10-03T14:14:37.270 に答える
1

おそらく、「可能な限り最速の方法」(そして、C++ としては有効ですが、可能な限り最も C++ らしい方法) は、次のようなものです。

const unsigned dim1 = 10; //first dimension
const unsigned dim2 = 20; //second
const unsigned dim3 = 30; //third
const unsigned nElem = dim1 * dim2 * dim3;

CLS myVec[nElem];

CLS *p = myVec, *q = myVec + nElem;

while (p < q)
{ foo(*p);
  ++p;
}

これにより、配列内の位置ではなく、問題foo()の要素の値のみに依存するように見えるため、インデックスのすべての計算が不要になります。CLSもちろん、myVec3D っぽい方法でのアクセスはより複雑になります (myVec[x * dim1 * dim2 + y * dim1 + z]など - C++ が通常行うすべてのインデックス計算を明示的に行うだけです...)。

配列を「スライス」するようにループを変更して、1 つの次元が一定に保たれるようにすると、少し複雑になります (基本的に、内部ループの終了時にポインターに追加のオフセットを追加する、二重にネストされたループにします)。これに少し似ています(ただし、寸法が逆になっている場合があります):

while (p < q)
{ CLS *r = p + dim3;
  while (p < r)
  { foo(*p);
    ++p;
  }
  p += dim2;
}
于 2012-10-03T14:24:28.097 に答える
0

再帰関数オブジェクトを作成できます。

class Foo {
public:
    template<typename Container>
    void operator()(Container& container) {
        for_each(container.begin(), container.end(), *this);
    }
    void operator()(CLS cls) {
        // do what you want
    }
};

Foo foo;
foo(myVec);
于 2012-10-03T14:42:45.207 に答える