c ++在3D矢量上最快的循环扫描

时间:2012-10-03 13:59:35

标签: c++ performance for-loop stdvector

我想知道在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或建议使用其他类型的容器?

期待您的帮助。谢谢

5 个答案:

答案 0 :(得分: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
   }
} 

如果您对尺寸有所了解,可以再展开一次。

答案 1 :(得分: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);
    }
}

我没有测量它(虽然甚至没有尝试编译,所以原谅任何错别字)

答案 2 :(得分: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元素的值,而不取决于它在数组中的位置。当然,以3D方式访问myVec变得更加复杂(myVec[x * dim1 * dim2 + y * dim1 + z]等等 - 只是明确了C ++通常为您做的所有索引计算......)。

更改循环以“切片”数组以使一个维度保持不变会使它更复杂一些(实际上使它成为一个双嵌套循环,在内循环终点处为指针添加一个额外的偏移量)。有点像这样(虽然我可能有相反的尺寸):

while (p < q)
{ CLS *r = p + dim3;
  while (p < r)
  { foo(*p);
    ++p;
  }
  p += dim2;
}

答案 3 :(得分: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);

答案 4 :(得分:0)

如果你想要效率,为什么要在3个循环中完成?

这是一个1

int cycle,
    i = 0,
    j = 0,
    counter;

for(cycle = 0, counter = 0; cycle < 10; counter++)
{
    j = counter % myVec[i][constant].size(); // It will go between 0 - myVec[i][constant].size()
    i += (!j) * !(!counter); // If j is reset (j =
    i %= myVec.size();
    foo(myVec[i][constant][j]); // Do your function
    cycle += (!i) * (!j) * !(!counter);
}

j = counter % myVec[i][constant].size()它将介于0myVec[i][constant].size()

之间

i += (!j) * !(!counter)如果重置jj等于0),请将其设为1如果{ {1}} counter0 = !(!0) = !1},如果它比0更大,那么0例如5 {1}} = !(!5) = !0)所以1增加1

i它将在i %= myVec.size()0之间转换,并在到达myVec.size()时重新开始i = 0

myVec.size()你的功能

foo(myVec[i][constant][j])如果重置cycle += (!i) * (!j) * !(!counter)i等于i),请将其设为01 相同但如果j大于counter0增加1