我正在同时学习C++和OpenCV。我正在阅读以下内容,这一点尚不清楚,为什么按值传递参数通常会使编译器的代码优化更加容易。
void salt(Mat image, int n)
{
default_random_engine generator;
uniform_int_distribution<int> randomRow(0, image.rows - 1);
uniform_int_distribution<int> randomCol(0, image.cols - 1);
for (int k = 0; k < n; k++)
{
int i = randomCol(generator);
int j = randomRow(generator);
if (image.type() == CV_8UC1)
image.at<uchar>(j, i) = 255;
else if (image.type() == CV_8UC3)
image.at<Vec3b>(j, i) = Vec3b(255, 0, 0);
}
}
最佳答案
用两个词表示:别名分析。请记住,(例如)const int &r
不会将r
声明为对不变的整数的引用,而是对不可用于对其进行更改的整数的引用。因此,只要对int
的引用写入任何内容,就必须重新加载r
的值,并且不会发生常见的子表达式消除和代码移动。如果r
是本地r
对象,则编译器通常可以证明其地址永不转义;否则,编译器将继续执行该操作。那么它就可以忽略对其他任何内容的写操作,通常允许int
保留在寄存器中或尽早丢弃。
这在您引用的段落中被放在一边,因为在所讨论的情况下它不太重要:r
必须包含指向基础图像数据的指针,因此即使Mat
通过值传递,也可能会出现别名。 (能够证明有关指针本身的东西可能会带来一些好处,但必须以牺牲引用计数或类似费用为代价。)