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 是否足够快,或者您建议使用其他类型的容器?

期待您的帮助。谢谢

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

更改循环以“切片”数组以使一维保持不变会使其变得更加复杂(本质上使其成为双重嵌套循环,在内部循环的终止处为指针添加额外的偏移量)。有点像这样(尽管我的尺寸可能颠倒了):

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 回答