Related
Is passing argument by reference/using pointer better for overall performance of program, than passing it normally?
From the logic POV it's because there are no copies of already stored variables, but is it really?
I know, that passing every argument by reference could be harmful, but I am refering to situations, where there's even simple variable passed, that is not used later in overall code, so its change wouldn't even affect anything.
I was wondering, because I've noticed that a lot of fellow programmers use that in their code.
I just want to know, I realize, that such tweaks won't speed up program much, but that's for my conciousness about the code.
I know, that passing every argument by reference could be harmful...
Using a const reference will prevent the altering of the object you pass, so it's safe.
Is passing argument by reference/using pointer better for overall performance of program, than passing it normally?
From the logic POV it's because there are no copies of already stored variables, but is it really?
Your question applies to passing variables to use its values but not change them:
In the case of, for instace:
void test(const int& value);
Call
int i;
test(i);
The differences in performance and/or space are near to none, for primitive types, you need not to bother with this.
But if you have complex type objects their size ceases to be negligible, their size is almost always bigger than the size of a pointer and copying them might result in non negligible performance loss, in this case it's better to pass by reference, you are passing the address of that variable and this avoids unnecessary copies.
class Complex{
//data members inside
};
void test(const Complex& c){
complex c;
test(c);
}
Call
Complex c;
test(c);
Is passing argument by reference/using pointer better for overall performance of program, than passing it normally?
It depends. In some cases it is better than passing by value, in some other cases it is worse, and in rest of the cases it doesn't matter. If you want to know whether passing a value or a reference is faster in some particular case, you need to measure.
From the logic POV it is, because there are no copies of already stored
On the other hand, you are now not only copying a reference, but also indirecting through it to access the object.
Rule of thumb: In case you are passing an argument without intention of storing a copy for later, use a reference unless the type is trivially copyable and the size of a pointer or smaller. If you write a template and type could be either, then assume it is slow to copy and use a reference.
This question already has answers here:
Returning a const reference to an object instead of a copy
(12 answers)
Closed 8 years ago.
Now, this is highly conceptual. I don't know if I understand this correctly, so please help me understand the difference.
Let's assume that name is a private std::string data member that is accessed by the getName() accessor function:
const string& getName() const {
return name;
}
Now then, this returns a reference, which is just another word for alias, to name. So, an alias is being returned, i.e. the name data member is being returned. Is this allowed or will it defeat the whole purpose of data hiding?
In other words, how exactly is the above method different to the conventional:
string getName() const {
return name;
}
???
And finally, is it really worth implementing the former instead of the latter?
First of all, the reference would be problematic indeed if the underlying value could change, particularly in the context of multi-threaded execution. So it's almost a basic assumption that the value of the data member doesn't change during the lifetime of the object. That it's effectively a constant.
Now, a main problem with the reference is that it exposes an implementation detail so that it gets difficult to change the implementation.
A more academic problem is that it can break code, if there earlier was a by-value return, or just because it's unusual. E.g.
const string s& = foo().name();
With foo() returning an object by value, and name() returning a string by reference, this gives you a dangling reference instead of the naïvely expected prolonged lifetime. I call it academic because I can't imagine anyone writing that. Still, Murphy's law and all that.
It will probably not be (significantly) more efficient than a value return, precisely because it's unlikely that it's used just to initialize a reference.
So:
probably not significantly more efficient,
prevents changing implementation easily,
also has an academic problem, yielding dangling references.
In sum, just don't.
This is premature optimization and complication.
The first allows callers some-what direct access to your internal name variable. Granted it's constant, so they can only call const methods on it. But still do you want external callers operating on your hidden, internal data? Even worse, what if some bozo decides to const_cast the internal data buffer of the string and hack on it?
The second returns a copy of your internal name variable. Perfectly safe for any callers to use.
I usually steer away from the first type, except for trivial, low level types. But then trivial low level types don't have much overhead for copying anyways. So that means I never write stuff like that.
The const reference return is better since it does not make a copy of the string. The reason I say this is because the interface is more flexible this way - you can always copy the const reference into another string if needed or you can use it as a reference - up to the caller. Returning a member byvalue and you are always stuck with making a copy. If name is big or used often, then it will impact performance and I assume performance is one of the reasons you use C++ in the first place.
Now, the other answers raise some negative points about returning a const reference, which I do not think are valid.
The concern that you can cast away the const, is valid, but casting away const is just one of the tools in the C++ developer's toolbox. Why take it away? If someone really wants to mess with your object, they can always do so in c++ by addressing memory directly so designing your code to save your callers from themselves is pointless. Casting the const away shows intent to do so and in my opinion is perfectly OK. It means that the caller has some very specific reasons to do so and knows that the const being cast away is for a non-const object and therefore - safe.
The academic example in the other answer is just silly:
const string s& = foo().name();
Again, designing your code to attempt to save the caller from themselves is limiting you from the power of C++. If one would really want to do the above, the proper way would be
string s = foo().name();
So that point is moot too.
The only valid point is that it exposes the implementation somewhat. The efficiency gains, however, outweigh this concern in my opinion.
What you really should ask yourself is this - what is the usual case of using name()?
By answering this question, you will answer which flavour you should use.
To me, the fact that it is called name implies that it will mostly be used for printing/logging and comparison. Therefore, the const reference is the clear winner here.
Also, look at the style guides out there. Most of them will have you pass by const reference and return members by const reference. There are very good reasons to do so as outlined above.
In a practical environment, using gcc or MS Visual Studio, is it bad to pass the value types which are the same size or less than an int by const reference ?
i.e. is it bad to write such a function:
void f(const bool& b);
or
void f(const char& c);
rather than:
void f(bool b);
or
void f(char c);
The reason I am asking is that I do not see the benefit of passing a reference in these cases but maybe I am missing something.
It may be slightly bad, or it may not have an effect at all (depends on where the original value is stored, how good the optimizer is, and how it decides to treat your code).
The standard doesn't mandate how references are to be implemented, but in practice compilers implement references using pointers. Therefore in the general case a bool& would be implemented using a bool*, which means that to access the bool you need an extra pointer dereference each time. Since a bool is no bigger than a pointer, there's no reduced memory footprint or less byte copying to offset this drawback.
As a result the accepted practice is to pass primitives around as values since it's more efficient. Of course although passing such around as references won't really blow up anything, and unless you are accessing the value inside a loop will probably not even result in any measurable difference.
Performance aside, there are actually cases where you will get different behavior.
For instance, passing a const reference makes sure that the function cannot change the value of the referenced variable, but another thread might do so. If you pass by reference (even with const), you will see these changes, if you pass by value, you will not.
Also, the definition of the interface limits what you can do with the variable inside the function. Consider this example:
int foo(int a) {
a = 5; // valid
}
int bar(const int& a) {
a = 5; // compiler-error
}
If you pass by reference, and you want to modify the value of the variable for local use, you need to make an extra copy. If you pass by value, you already have a copy.
One reason would be that you would like to convey to other programmers that the value is constant, it may in some cases be clearer although const bool would suffice.
I think it's better to pass builtin types by value rather then const reference since it's virtually faster. In case of passing by reference you need to create a reference (i.e. take an address) and then dereference when using the variable. In most cases it will be optimized by compiler in any case though
It really doesn't matter, passing by value makes cleaner code thou and is therefore considered good practice.
Although in theory it won't be a good idea, as references are usually implemented using pointers. But nevertheless every reasonable compiler should be smart enough to recognize the indifference in semantics between by-const-reference and by-value for fundamental types.
Often you don't have a choice if you have some kind of templated interface that has to work for complex types and fundamental types and you don't want excessive specialization overhead (simplest example: std::vector). But if you have a choice, then passing fundamental types by-value should be preferred.
class I {
public:
virtual std::wstring const& GetName() const = 0;
};
Usually clients which implement this interface contain their name inside their body. And everything works just fine. But sometimes the result of 'GetName' is calculated during function execution. Using static variable to store result is not a very good idea. But returning by value requires additional performance overhead.
So how this problem could be solved? Thanks.
But returning by value requires
additional performance overhead.
This is not true. The compiler will very often be able to elide the copy using Return Value Optimization.
OK in what sense? It's legal C++. It's usually very poor programming
practice, for the reason you mention: it imposes a (usually) unnecessary
restriction on derived classes. Independently of virtual, you should
only return a reference when the semantics of the function require it;
if the type has value semantics, like std::string, then this would
only be a non-const reference. (Templates complicate the issue somewhat,
and it is reasonable for classes like std::vector to return a
reference to const from operator[] const.)
It seems like a bad idea. If the overhead really matters, you could use some string container with implicit sharing (copy-on-write semantics), like QString.
Don't guess performance issues: while people often return std::string by const reference, it is really not a big deal to return one by value, especially if you have no other choice.
Actually, you can sometimes even change that latter as it affects only a few things for the client code.
Remember: premature optimization is the root of all evil.
Now, to fully answer the question, you can perfectly return a reference in virtual function (whether it is pure or not doesn't really matter). Just ensure never to return a reference to a temporary.
If some derived class needs to perform a costly computation, it can still store the result in a member std::wstring and return a reference to that. But once again, don't guess performance issues: measure first and focus on it only if this seems to be the bottleneck.
Though everyone else seems to agree that it is a very bad idea (for a variety of reasons, all of which are somewhat true), I don't see anything fundamentally wrong with returning a string const&.
Doing so
is technically legitimate and will work just fine (it merely lays down a "contract" that the deriving classes must fulfill in some yet-unspecified way)
is probably an insignificant micro-optimization (which also is likely none different from RVO in an optimized build), but it does not hurt either... insofar, so what
does not allow the caller to modify the name, which makes sense (the caller is not competent to do so, it's why he had to ask in the first place!) -- this is semantically actually a good thing
will work regardless of the actual yet-unknown implementation, even with temporaries (since for const references, the standard extends the lifetime of local variables to the lifetime of the reference)
So, although kind of unusual, if it does what you want (especially making explicit that the caller may not modify the string), I see no absolute reason not to do it.
Which of the following examples is the better way of declaring the following function and why?
void myFunction (const int &myArgument);
or
void myFunction (int myArgument);
Use const T & arg if sizeof(T)>sizeof(void*) and use T arg if sizeof(T) <= sizeof(void*)
They do different things. const T& makes the function take a reference to the variable. On the other hand, T arg will call the copy constructor of the object and passes the copy.
If the copy constructor is not accessible (e.g. it's private), T arg won't work:
class Demo {
public: Demo() {}
private: Demo(const Demo& t) { }
};
void foo(Demo t) { }
int main() {
Demo t;
foo(t); // error: cannot copy `t`.
return 0;
}
For small values like primitive types (where all matters is the contents of the object, not the actual referential identity; say, it's not a handle or something), T arg is generally preferred. For large objects and objects that you can't copy and/or preserving referential identity is important (regardless of the size), passing the reference is preferred.
Another advantage of T arg is that since it's a copy, the callee cannot maliciously alter the original value. It can freely mutate the variable like any local variables to do its work.
Taken from Move constructors. I like the easy rules
If the function intends to change the argument as a side effect, take it by reference/pointer to a non-const object. Example:
void Transmogrify(Widget& toChange);
void Increment(int* pToBump);
If the function doesn't modify its argument and the argument is of primitive type, take it by value. Example:
double Cube(double value);
Otherwise
3.1. If the function always makes a copy of its argument inside, take it by value.
3.2. If the function never makes a copy of its argument, take it by reference to const.
3.3. Added by me: If the function sometimes makes a copy, then decide on gut feeling: If the copy is done almost always, then take by value. If the copy is done half of the time, go the safe way and take by reference to const.
In your case, you should take the int by value, because you don't intend to modify the argument, and the argument is of primitive type. I think of "primitive type" as either a non-class type or a type without a user defined copy constructor and where sizeof(T) is only a couple of bytes.
There's a popular advice that states that the method of passing ("by value" vs "by const reference") should be chosen depending in the actual size of the type you are going to pass. Even in this discussion you have an answer labeled as "correct" that suggests exactly that.
In reality, basing your decision on the size of the type is not only incorrect, this is a major and rather blatant design error, revealing a serious lack of intuition/understanding of good programming practices.
Decisions based on the actual implementation-dependent physical sizes of the objects must be left to the compiler as often as possible. Trying to "tailor" your code to these sizes by hard-coding the passing method is a completely counterproductive waste of effort in 99 cases out of 100. (Yes, it is true, that in case of C++ language, the compiler doesn't have enough freedom to use these methods interchangeably - they are not really interchangeable in C++ in general case. Although, if necessary, a proper size-based [semi-]automatic passing methios selection might be implemented through template metaprogramming; but that's a different story).
The much more meaningful criterion for selecting the passing method when you write the code "by hand" might sound as follows:
Prefer to pass "by value" when you are passing an atomic, unitary, indivisible entity, such as a single non-aggregate value of any type - a number, a pointer, an iterator. Note that, for example, iterators are unitary values at the logical level. So, prefer to pass iterators by value, regardless of whether their actual size is greater than sizeof(void*). (STL implementation does exactly that, BTW).
Prefer to pass "by const reference" when you are passing an aggregate, compound value of any kind. i.e. a value that has exposed pronouncedly "compound" nature at the logical level, even if its size is no greater than sizeof(void*).
The separation between the two is not always clear, but that how things always are with all such recommendations. Moreover, the separation into "atomic" and "compound" entities might depend on the specifics of your design, so the decision might actually differ from one design to the other.
Note, that this rule might produce decisions different from those of the allegedly "correct" size-based method mentioned in this discussion.
As an example, it is interesing to observe, that the size-based method will suggest you manually hard-code different passing methods for different kinds of iterators, depending on their physical size. This makes is especially obvious how bogus the size-based method is.
Once again, one of the basic principles from which good programming practices derive, is to avoid basing your decisions on physical characteristics of the platform (as much as possible). Instead, you decisions have to be based on the logical and conceptual properties of the entities in your program (as much as possible). The issue of passing "by value" or "by reference" is no exception here.
In C++11 introduction of move semantics into the language produced a notable shift in the relative priorities of different parameter-passing methods. Under certain circumstances it might become perfectly feasible to pass even complex objects by value
Should all/most setter functions in C++11 be written as function templates accepting universal references?
Contrary to popular and long-held beliefs, passing by const reference isn't necessarily faster even when you're passing a large object. You might want to read Dave Abrahams recent article on this very subject.
Edit: (mostly in response to Jeff Hardy's comments): It's true that passing by const reference is probably the "safest" alternative under the largest number of circumstances -- but that doesn't mean it's always the best thing to do. But, to understand what's being discussed here, you really do need to read Dave's entire article quite carefully, as it is fairly technical, and the reasoning behind its conclusions is not always intuitively obvious (and you need to understand the reasoning to make intelligent choices).
Usually for built-in types you can just pass by value. They're small types.
For user defined types (or templates, when you don't what is going to be passed) prefer const&. The size of a reference is probably smaller than the size of the type. And it won't incurr an extra copy (no call to a copy constructor).
Well, yes ... the other answers about efficiency are true. But there's something else going on here which is important - passing a class by value creates a copy and, therefore, invokes the copy constructor. If you're doing fancy stuff there, it's another reason to use references.
A reference to const T is not worth the typing effort in case of scalar types like int, double, etc. The rule of thumb is that class-types should be accepted via ref-to-const. But for iterators (which could be class-types) we often make an exception.
In generic code you should probably write "T const&" most of the time to be on the safe side. There's also boost's call traits you can use to select the most promising parameter passing type. It basically uses ref-to-const for class types and pass-by-value for scalar types as far as I can tell.
But there are also situations where you might want to accept parameters by value, regardless of how expensive creating a copy can be. See Dave's article "Want Speed? Use pass by value!".
For simple types like int, double and char*, it makes sense to pass it by value. For more complex types, I use const T& unless there is a specific reason not to.
The cost of passing a 4 - 8 byte parameter is as low as you can get. You don't buy anything by passing a reference. For larger types, passing them by value can be expensive.
It won't make any difference for an int, as when you use a reference the memory address still has to be passed, and the memory address (void*) is usually about the size of an integer.
For types that contain a lot of data it becomes far more efficient as it avoids the huge overhead from having to copy the data.
Well the difference between the two doesn't really mean much for ints.
However, when using larger structures (or objects), the first method you used, pass by const reference, gives you access to the structure without need to copy it. The second case pass by value will instantiate a new structure that will have the same value as the argument.
In both cases you see this in the caller
myFunct(item);
To the caller, item will not be changed by myFunct, but the pass by reference will not incur the cost of creating a copy.
There is a very good answer to a similar question over at Pass by Reference / Value in C++
The difference between them is that one passes an int (which gets copied), and one uses the existing int. Since it's a const reference, it doesn't get changed, so it works much the same. The big difference here is that the function can alter the value of the int locally, but not the const reference. (I suppose some idiot could do the same thing with const_cast<>, or at least try to.) For larger objects, I can think of two differences.
First, some objects simply can't get copied, auto_ptr<>s and objects containing them being the obvious example.
Second, for large and complicated objects it's faster to pass by const reference than to copy. It's usually not a big deal, but passing objects by const reference is a useful habit to get into.
Either works fine. Don't waste your time worrying about this stuff.
The only time it might make a difference is when the type is a large struct, which might be expensive to pass on the stack. In that case, passing the arg as a pointer or a reference is (slightly) more efficient.
The problem appears when you are passing objects. If you pass by value, the copy constructor will be called. If you haven't implemented one, then a shallow copy of that object will be passed to the function.
Why is this a problem? If you have pointers to dynamically allocated memory, this could be freed when the destructor of the copy is called (when the object leaves the function's scope). Then, when you re call your destructor, youll have a double free.
Moral: Write your copy constructors.