C++ 犰狳库方括号[]和括号()之间的差异
犰狳图书馆提供了三种方法:C++ 犰狳库方括号[]和括号()之间的差异,c++,armadillo,C++,Armadillo,犰狳图书馆提供了三种方法: 通过() 通过[] 通过at() 我注意到在使用它们的时候,它们的性能是不同的。我测试了下面的代码: size_t n_row = 500, n_col = 500; { // () wall_clock timer; mat matrix(n_row, n_col, fill::zeros); timer.tic(); for (size_t i = 0; i < n_row; i++){ for (size_
()
李>
[]
李>
at()
李>
我注意到在使用它们的时候,它们的性能是不同的。我测试了下面的代码:
size_t n_row = 500, n_col = 500;
{ // ()
wall_clock timer;
mat matrix(n_row, n_col, fill::zeros);
timer.tic();
for (size_t i = 0; i < n_row; i++){
for (size_t j = 0; j < n_col; j++){
matrix(i, j) = i+j;
}
}
std::cout << timer.toc() << std::endl;
}
{ // []
wall_clock timer;
mat matrix(n_row, n_col, fill::zeros);
timer.tic();
for (size_t i = 0; i < n_row; i++){
for (size_t j = 0; j < n_col; j++){
matrix[i, j] = i+j;
}
}
std::cout << timer.toc() << std::endl;
}
{ // .at()
wall_clock timer;
mat matrix(n_row, n_col, fill::zeros);
timer.tic();
for (size_t i = 0; i < n_row; i++){
for (size_t j = 0; j < n_col; j++){
matrix.at(i, j) = i+j;
}
}
std::cout << timer.toc() << std::endl;
}
大小n列=500,n列=500;
{ // ()
挂钟计时器;
mat矩阵(n_行,n_列,填充::零);
timer.tic();
对于(大小i=0;i 答案主要在你给出的链接中:
.at(n)
或[n]
与(n)相同,但没有边界检查。除非您的代码已彻底调试,否则不建议使用
- 所以答案的第一部分是,
.at(n)
和[n]
可能比(n)
稍快,但安全性较差,这可能就是()
访问在测试中花费时间最长的原因
- 但是
[n]
和.at(n)
是一样的,你所看到的时间上的差异只是你运行测试的方式或计时的方式的相同产物。这并不奇怪,因为基准测试是出了名的困难,它不仅仅是在循环中运行某个东西并在你正在做的时候计时。(实际上,这甚至可能是您在()
中看到的时差的真正原因)
- 此约定与STL容器有着令人困惑的不同:通常,
[]
未选中,.at()
已选中,而用于索引的()
根本不存在
- 还有
(i,j)
和。at(i,j)
和(i,j,k)
和。at(i,j,k)
,但没有[i,j]
或[i,j,k]
。
- 因此,
.at()
和[]
看似重复存在的原因是,[]
不适用于多个索引(但可能仍然适用于单索引情况,因为它比.at()
自然得多)
- 链接中没有提到这一点,但这是因为C++不允许用多个参数重载<代码>操作符[]/Cuff>函数,因此这总是被解释为<代码>(i,j)]/COD>,最终被评估为<代码> [i]<代码> -评估<代码> j/COD>(例如,如果它是函数调用)但随后就悄悄地扔掉了
实际上,在大多数应用程序中,检查索引访问不太可能成为瓶颈,而且在许多情况下,编译器可能会完全优化它(至少在发布模式下)。因此,我的建议是始终使用圆括号mat(ind)
表示法。谢谢您的回答,但我在配置文件中设置了#define ARMA_NO_DEBUG
。这将关闭所有boudary检查。我还可以使用[I,j]
索引和它的工作原理在这种情况下,你所看到的时间上的全部差异是由于随机波动。尝试用完全相同的索引方法替换三种不同的索引方法复制和粘贴三次,你肯定会看到相同的波动。至于[i,j]< /Cord>索引,我保证这不会起作用,在C++中是不可能的。作为额外的证据,它显然不支持ARMADILO文档和整个原因<代码>。
exists允许使用多个参数进行检查索引。它将编译,但会给出错误的结果:实际上,j
完全被忽略,原因是我在回答中提到过,而且犰狳在为2d矩阵提供一个索引时会进行线性索引。[编辑:或者可能是i
被忽略了,但重点是相同的。]是的,[i,j]
索引给了我错误的结果。谢谢!Armadillo指出,在检测并删除代码中的所有错误之前,\define ARMA\u NO\u DEBUG
不是一个好主意。