Re: Why is there no input value optimization?
Am 10.04.2012 11:18, schrieb rossmpublic@gmail.com:
I have a very simple question that I have been unable to find a
satisfactory answer. The question is why do I need to manually
optimize my functions using const references?
For example:
// Optimized passing of string parameter
Widget(std::string const & name);
SetName(std::string const & name);
// Non-optimized passing of string parameter
Widget(std::string name);
SetName(std::string name);
Even worse:
// optimized passing of int parameter
void foo(int i);
// pessimized passing of int parameter
void foo(int const& i);
// probably pessimized passing of pair
void bar(std::pair<int, int> const& p);
// and what about this here??
SetName(std::string name) { this->name.swap(name); }
The performance of course depends on the actual implementation, but in
common implementations a reference is just a "self-dereferencing
pointer", so a reference requires another level of indirection. Also,
any function can cheat and const_cast, so a calling function must not
assume that the call doesn't modify the passed object. Making informed
predictions requires looking at the implementation of the function,
which is the reason that many modern compiler perform optimizations
across translation-unit boundaries.
Note that the thing with the int and pair above is something I learned
from micro-optimizing some code. Certain code. On one particular
platform. In a very tight loop. I don't claim that this is universally
the most performant way.
I understand that with the latter notation there is an additional
copy involved on most compilers, but why is that exactly? Why is it
that the compiler (as smart as it is today) is unable to optimize
away the additional copy?
I think that it is possible to elide copying. Passing an object into a
function is very similar to returning it from a function, and RVO is
commonplace nowadays. If the compiler knows that an object is not
modified inside a function, it can exploit that knowledge.
Why should I be writing optimization code into my interfaces?? This
seems very wrong to me.
I agree. The compiler should figure out the fastest way itself. This
isn't trivial though:
struct weird {
string X;
void set_with_brackets(string x) {
X = "<";
X += x;
X += ">";
}
};
weird thing = { "argh!" };
thing.set_with_brackets(thing.X);
If you change the parameter to a reference, this code suddenly changes
its result! The "const&" makes sure that you don't accidentally modify
it through this reference, it doesn't guarantee that the object itself
isn't changed by other means.
I understand that the language probably cannot guarantee that there
will not be a copy but why haven't the compilers stepped up with this sort
of optimization as was done with return value optimization?
I guess that there are two reasons:
1. People are used to it, the "const&" is something that the brain has
learned to ignore. Further, this is only written in one or two places.
2. If you pass the object to modify as reference to the function, which
is a common way to avoid copying, you sacrifice the ability to chain
functions, you need two lines of code, you can't declare the object
const etc. This hurts much more than declaring the passed parameter as
reference to const in two places!
Uli
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]