I am learning both C++ and OpenCV in parallel. I am reading the following that is a bit unclear why pass-by-value parameters often makes code optimization easier for the compiler.
As a last note, you might have been surprised by the fact that our image modifying function uses a pass-by-value image parameter. This works because when images are copied, they still share the same image data. So, you do not necessarily have to transmit images by references when you want to modify their content. Incidentally, pass-by-value parameters often make code optimization easier for the compiler.
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);
}
}
In two words: alias analysis. Remember that (for example) const int &r
does not declare r
to be a reference to an unchanging integer but a reference to an integer that may not be used to change it. So any time that a write to any int
might be to r
’s referent, the value of r
must be reloaded, and common subexpression elimination and code motion cannot occur. If r
is a local int
object, the compiler can often prove that its address never escapes; then it can ignore any write to anything else, often allowing r
to stay in a register or be discarded early.
This was given as an aside in the passage you quoted because it is less important in the case in question: Mat
must contain a pointer to the underlying image data, so some aliasing is possible even when a Mat
is passed by value. (Being able to prove things about the pointer itself may give some benefit, but that must be set against the expense of reference counting or similar.)