Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it better to pass by value or by reference for basic datatypes?
Reasons to not pass simple types by reference?
I did some testing where I had two scenarios, each with two identical functions- one passing the parameter by reference and the other by value. The scenario with strings showed a massive performance increase (because a copy of string is made, calling a constructor) whereas the test with long didn't show any performance increase when passing the value by reference. In fact, sometimes the performance was worse.
Is this expected with primitive types? Is there no point passing them by reference?
I was expecting a copy of a primitive type is made when not using by reference and therefore expected a small performance-boost.
You get the best performance from passing primitive types by value. This is because:
primitives are blitable, so the cost of the copy depends on the size
primitives are small, only double and long long are bigger than a reference in most environments
pass-by-value avoids aliasing, allowing the optimizer to really do its thing
This last point is often overlooked but can make a considerable difference.
Yes, that's the expected behavior. When you're passing parameters by reference, you're actually passing an address of the variable (like with pointer). Usually address is a 4 or 8-byte integer, so unless your primitive type is larger than that, you won't gain any performance improvement (and even if it's larger, you probably won't)
Modern compilers are pretty clever, so if the function isn't "hidden" (that is, part of something the compiler can't see at the time of producing the code), it may well make no difference at all. HOwever, if it the compiler follows your instructions, passing simple types as reference does potentially make a big difference. Particularly if the value is updated many times in the code.
I saw some code where I worked, which did something like this:
void SomeClass::FindLength(int &len)
{
listEntry* list = theList; // theList is a member variable.
len = 0;
while (list)
{
len++;
list = list->next;
}
}
By alterning the code to do:
void SomeClass::FindLength(int &len)
{
listEntry* list = theList; // theList is a member variable.
int tempLen = 0;
while (list)
{
tempLen++;
list = list->next;
}
len = tempLen;
}
the whole code ran some 30% faster, and called from a lot of places (and I think there was some if-condition in the middle, so we couldn't just keep track of the length). And since it was part of an API function, it wasn't possible to change the function signature.
The reason it was slower using the reference is that the compiler would write to the reference value EVERY time it was updated, which was a load from memory to register, increment register and a store register to memory. With the tempLen solution, the compiler could use a register, which is much faster.
In c++ reference is just convinient way to use pointers. When you use pointer you adding additional indirection. Copying primitive types as cheap as copying pointer.
That is why primitive types passed by reference a bit slower
Because you used c tag, I guess you are speaking about pointers (not explicit references from C++).
With pointers, you have two memory access: the pointer and the pointed value. So there is no particular gain of performances. Moreover, the compiler can do more optimisations with values: there is no aliasing problems, for example.
Is this expected with primitive types?
I'd say absolutely. They don't have constructors, so that doesn't need to be called.
Is there no point passing them by reference?
There is: when you want to have output parameters, then, in C++, passing by reference is considered better pracitce than passing a pointer.
I was expecting a copy of a primitive type is made when not using by reference and therefore expected a small performance-boost.
Well, since passing by reference is usually implemented using pointers, then the compiler has to emit code that pushes something onto the stack, either the value, or a pointer to the value - and it really does not matter which one is done.
When you pass a value by reference the function must dereference it to obtain the value, and each time you modify the value a dereference must occur too since you are writing it in a memory location. I guess compilers are able to understand when something won't be stored back in its reference location so that the value is modified just on registers and stored back just when needed but I'm not sure how powerful this is.
So there is an indirect step that is not present while passing parameters by value, which can cause worse performance but it's really foggy since compiler optimizations come into place. Think about the fact that you are passing a pointer, every time you need the value you must fetch the pointer from the stack and then fetch the value pointed (so there are two accesses), while with a normal parameter you have just one (fetching the value).
In any case, a reference is used for purposes that are surely different from performance, like modifying the passed parameter locally.
Is it better in C++ to pass by value or pass by reference-to-const?
I am wondering which is better practice. I realize that pass by reference-to-const should provide for better performance in the program because you are not making a copy of the variable.
It used to be generally recommended best practice1 to use pass by const ref for all types, except for builtin types (char, int, double, etc.), for iterators and for function objects (lambdas, classes deriving from std::*_function).
This was especially true before the existence of move semantics. The reason is simple: if you passed by value, a copy of the object had to be made and, except for very small objects, this is always more expensive than passing a reference.
With C++11, we have gained move semantics. In a nutshell, move semantics permit that, in some cases, an object can be passed “by value” without copying it. In particular, this is the case when the object that you are passing is an rvalue.
In itself, moving an object is still at least as expensive as passing by reference. However, in many cases a function will internally copy an object anyway — i.e. it will take ownership of the argument.2
In these situations we have the following (simplified) trade-off:
We can pass the object by reference, then copy internally.
We can pass the object by value.
“Pass by value” still causes the object to be copied, unless the object is an rvalue. In the case of an rvalue, the object can be moved instead, so that the second case is suddenly no longer “copy, then move” but “move, then (potentially) move again”.
For large objects that implement proper move constructors (such as vectors, strings …), the second case is then vastly more efficient than the first. Therefore, it is recommended to use pass by value if the function takes ownership of the argument, and if the object type supports efficient moving.
A historical note:
In fact, any modern compiler should be able to figure out when passing by value is expensive, and implicitly convert the call to use a const ref if possible.
In theory. In practice, compilers can’t always change this without breaking the function’s binary interface. In some special cases (when the function is inlined) the copy will actually be elided if the compiler can figure out that the original object won’t be changed through the actions in the function.
But in general the compiler can’t determine this, and the advent of move semantics in C++ has made this optimisation much less relevant.
1 E.g. in Scott Meyers, Effective C++.
2 This is especially often true for object constructors, which may take arguments and store them internally to be part of the constructed object’s state.
Edit: New article by Dave Abrahams on cpp-next: Want speed? Pass by value.
Pass by value for structs where the copying is cheap has the additional advantage that the compiler may assume that the objects don't alias (are not the same objects). Using pass-by-reference the compiler cannot assume that always. Simple example:
foo * f;
void bar(foo g) {
g.i = 10;
f->i = 2;
g.i += 5;
}
the compiler can optimize it into
g.i = 15;
f->i = 2;
since it knows that f and g doesn't share the same location. if g was a reference (foo &), the compiler couldn't have assumed that. since g.i could then be aliased by f->i and have to have a value of 7. so the compiler would have to re-fetch the new value of g.i from memory.
For more pratical rules, here is a good set of rules found in Move Constructors article (highly recommended reading).
If the function intends to change the argument as a side effect, take it by non-const reference.
If the function doesn't modify its argument and the argument is of primitive type, take it by value.
Otherwise take it by const reference, except in the following cases
If the function would then need to make a copy of the const reference anyway, take it by value.
"Primitive" above means basically small data types that are a few bytes long and aren't polymorphic (iterators, function objects, etc...) or expensive to copy. In that paper, there is one other rule. The idea is that sometimes one wants to make a copy (in case the argument can't be modified), and sometimes one doesn't want (in case one wants to use the argument itself in the function if the argument was a temporary anyway, for example). The paper explains in detail how that can be done. In C++1x that technique can be used natively with language support. Until then, i would go with the above rules.
Examples: To make a string uppercase and return the uppercase version, one should always pass by value: One has to take a copy of it anyway (one couldn't change the const reference directly) - so better make it as transparent as possible to the caller and make that copy early so that the caller can optimize as much as possible - as detailed in that paper:
my::string uppercase(my::string s) { /* change s and return it */ }
However, if you don't need to change the parameter anyway, take it by reference to const:
bool all_uppercase(my::string const& s) {
/* check to see whether any character is uppercase */
}
However, if you the purpose of the parameter is to write something into the argument, then pass it by non-const reference
bool try_parse(T text, my::string &out) {
/* try to parse, write result into out */
}
Depends on the type. You are adding the small overhead of having to make a reference and dereference. For types with a size equal or smaller than pointers that are using the default copy ctor, it would probably be faster to pass by value.
As it has been pointed out, it depends on the type. For built-in data types, it is best to pass by value. Even some very small structures, such as a pair of ints can perform better by passing by value.
Here is an example, assume you have an integer value and you want pass it to another routine. If that value has been optimized to be stored in a register, then if you want to pass it be reference, it first must be stored in memory and then a pointer to that memory placed on the stack to perform the call. If it was being passed by value, all that is required is the register pushed onto the stack. (The details are a bit more complicated than that given different calling systems and CPUs).
If you are doing template programming, you are usually forced to always pass by const ref since you don't know the types being passed in. Passing penalties for passing something bad by value are much worse than the penalties of passing a built-in type by const ref.
This is what i normally work by when designing the interface of a non-template function:
Pass by value if the function does not want to modify the parameter and the
value is cheap to copy (int, double, float, char, bool, etc... Notice that std::string, std::vector, and the rest of the containers in the standard library are NOT)
Pass by const pointer if the value is expensive to copy and the function does
not want to modify the value pointed to and NULL is a value that the function handles.
Pass by non-const pointer if the value is expensive to copy and the function
wants to modify the value pointed to and NULL is a value that the function handles.
Pass by const reference when the value is expensive to copy and the function does not want to modify the value referred to and NULL would not be a valid value if a pointer was used instead.
Pass by non-const reference when the value is expensive to copy and the function wants to modify the value referred to and NULL would not be a valid value if a pointer was used instead.
Sounds like you got your answer. Passing by value is expensive, but gives you a copy to work with if you need it.
As a rule passing by const reference is better.
But if you need to modify you function argument locally you should better use passing by value.
For some basic types the performance in general the same both for passing by value and by reference. Actually reference internally represented by pointer, that is why you can expect for instance that for pointer both passing are the same in terms of performance, or even passing by value can be faster because of needless dereference.
Pass by value for small types.
Pass by const references for big types (the definition of big can vary between machines) BUT, in C++11, pass by value if you are going to consume the data, since you can exploit move semantics. For example:
class Person {
public:
Person(std::string name) : name_(std::move(name)) {}
private:
std::string name_;
};
Now the calling code would do:
Person p(std::string("Albert"));
And only one object would be created and moved directly into member name_ in class Person. If you pass by const reference, a copy will have to be made for putting it into name_.
As a rule of thumb, value for non-class types and const reference for classes.
If a class is really small it's probably better to pass by value, but the difference is minimal. What you really want to avoid is passing some gigantic class by value and having it all duplicated - this will make a huge difference if you're passing, say, a std::vector with quite a few elements in it.
Pass by referece is better than pass by value. I was solving the longest common subsequence problem on Leetcode. It was showing TLE for pass by value but accepted the code for pass by reference. Took me 30 mins to figure this out.
Simple difference :- In function we have input and output parameter , so if your passing input and out parameter is same then use call by reference else if input and output parameter are different then better to use call by value .
example void amount(int account , int deposit , int total )
input parameter : account , deposit
output paramteter: total
input and out is different use call by vaule
void amount(int total , int deposit )
input total deposit
output total
As title states I wish to know does Fortran intent(inout) pass a copy of the value, or a pointer/reference to RAM address? The reason I need to know this is I need to pass a (relatively) big data matrix. If it creates a local copy that would cause me problems. Thank you!
Fortran does not specify details of how function and subroutine arguments are passed, but it does require that if a procedure modifies an intent(out) or intent(inout) argument then the changes will be visible to the caller after the procedure returns. It is common for compilers to implement this requirement by passing arguments by reference, but that is not the only possibility -- copy in / copy out is the main alternative.
You can normally rely on the compiler to implement the fastest behavior it can be certain is correct, which is usually pass by reference. There are cases where that cannot work, however, such as passing a non-contiguous array section to an assumed-size dummy argument, and there are sometimes cases where copy-in / copy-out is faster (maybe on certain large multiprocessor systems with segmented memory architectures).
The bottom line is that although you pose a good question, there is no general answer. As is often the case, you are best off to make it work first, and then make it faster if needed. Keep the array-copying question in the back of your head, but don't worry too much about it until you are in a position to test.
With C++ how do i decide if i should pass an argument by value or by reference/pointer? (tell me the answer for both 32 and 64bits) Lets take A. Is 2 32bit values more less or equal work as a pointer to a 32bit value?
B to me seems like i always should pass by value. C i think i should pass by value but someone told me (however i haven't seen proof) that processors don't handle values not their bitsize and so it is more work. So if i were passing them around would it be more work to pass by value thus byref is faster? Finally i threw in an enum. I think enums should always be by value
Note: When i say by ref i mean a const reference or pointer (can't forget the const...)
struct A { int a, b; }
struct B { int a; }
struct C { char a, b; }
enum D { a,b,c }
void fn(T a);
Now tell me the answer if i were pushing the parameters many times and the code doesn't use a tail call? (lets say the values isnt used until 4 or so calls deep)
Forget the stack size. You should pass by reference if you want to change it, otherwise you should pass by value.
Preventing the sort of bugs introduced by allowing functions to change your data unexpectedly is far more important than a few bytes of wasted stack space.
If stack space becomes a problem, stop using so many levels (such as replacing a recursive solution with an iterative one) or expand your stack. Four levels of recursion isn't usually that onerous, unless your structures are massive or you're operating in the embedded world.
If performance becomes a problem, find a faster algorithm :-) If that's not possible, then you can look at passing by reference, but you need to understand that it's breaking the contract between caller and callee. If you can live with that, that's okay. I generally can't :-)
The intent of the value/reference dichotomy is to control what happens to the thing you pass as a parameter at the language level, not to fiddle with the way an implementation of the language works.
I pass all parameters by reference for consistency, including builtins (of course, const is used where possible).
I did test this in performance critical domains -- worst case loss compared to builtins was marginal. Reference can be quite a bit faster, for non-builtins, and when the calls are deep (as a generalization). This was important for me as I was doing quite a bit of deep TMP, where function bodies were tiny.
You might consider breaking that convention if you're counting instructions, the hardware is register-starved (e.g. embedded), or if the function is not a good candidate for inlining.
Unfortunately, the question you ask is more complex than it appears -- the answer may vary greatly by your platform, ABI, calling conventions, register counts, etc.
A lot depends on your requirement but best practice is to pass by reference as it reduces the memory foot print.
If you pass large objects by value, a copy of it is made in memory andthe copy constructor is called for making a copy of this.
So it will take more machine cycles and also, if you pass by value, changes are not reflected in the original object.
So try passing them by reference.
Hope this has been helpful to you.
Regards, Ken
First, reference and pointers aren't the same.
Pass by pointer
Pass parameters by pointers if any/some of these apply:
The passed element could be null.
The resource is allocated inside the called function and the caller is responsible should be responsible for freeing such a resource. Remember in this case to provide a free() function for that resource.
The value is of a variable type, like for example void*. When it's type is determined at runtime or depending on the usage pattern (or hiding implementation - i.e Win32 HANDLE), such as a thread procedure argument. (Here favor c++ templates and std::function, and use pointers for this purpose only if your environment does not permit otherwise.
Pass by reference
Pass parameters by reference if any/some of these apply:
Most of the time. (prefer passing by const reference)
If you want the modifications to the passed arguments to be visible to the caller. (unless const reference is used).
If the passed argument is never null.
If you know what is the passed argument type and you have control over function's signature.
Pass by copy
Pass a copy if any/some of these apply:
Generally try to avoid this.
If you want to operate on a copy of the passed argument. i.e you know that the called function would create a copy anyway.
With primitive types smaller than the system's pointer size - as it makes no performance/memory difference compared to a const ref.
This is tricky - when you know that the type implements a move constructor (such as std::string in C++11). It then looks as if you're passing by copy.
Any of these three lists can go more longer, but these are - I would say - the basic rules of thumb.
Your complete question is a bit unclear to me, but I can answer when you would use passing by value or by reference.
When passing by value, you have a complete copy of the parameter into the call stack. It's like you're making a local variable in the function call initialized with whatever you passed into it.
When passing by reference, you... well, pass by reference. The main difference is that you can modify the external object.
There is the benefit of reducing memory load for large objects passing by reference. For basic data types (32-bit or 64-bit integers, for example), the performance is negligible.
Generally, if you're going to work in C/C++ you should learn to use pointers. Passing objects as parameters will almost always be passed via a pointer (vs reference). The few instances you absolutely must use references is in the copy constructor. You'll want to use it in the operators as well, but it's not required.
Copying objects by value is usually a bad idea - more CPU to do the constructor function; more memory for the actual object. Use const to prevent the function modifying the object. The function signature should tell the caller what might happen to the referenced object.
Things like int, char, pointers are usually passed by value.
As to the structures you outlined, passing by value will not really matter. You need to do profiling to find out, but on the grand scheme of a program you be better off looking elsewhere for increasing performance in terms of CPU and/or memory.
I would consider whether you want value or reference semantics before you go worrying about optimizations. Generally you would pass by reference if you want the method you are calling to be able to modify the parameter. You can pass a pointer in this case, like you would in C, but idiomatic C++ tends to use references.
There is no rule that says that small types or enums should always be passed by value. There is plenty of code that passes int& parameters, because they rely on the semantics of passing by reference. Also, you should keep in mind that for any relatively small data type, you won't notice a difference in speed between passing by reference and by value.
That said, if you have a very large structure, you probably don't want to make lots of copies of it. This is where const references are handy. Do keep in mind though that const in C++ is not strictly enforced (even if it's considered bad practice, you can always const_cast it away). There is no reason to pass a const int& over an int, although there is a reason to pass a const ClassWithManyMembers& over a ClassWithManyMembers.
All of the structs that you listed I would say are fine to pass by value if you are intending them to be treated as values. Consider that if you call a function that takes one parameter of type struct Rectangle{int x, y, w, h}, this is the same as passing those 4 parameters independently, which is really not a big deal. Generally you should be more worried about the work that the copy constructor has to do - for example, passing a vector by value is probably not such a good idea, because it will have to dynamically allocate memory and iterate through a list whose size you don't know, and invoke many more copy constructors.
While you should keep all this in mind, a good general rule is: if you want refence semantics, pass by refence. Otherwise, pass intrinsics by value, and other things by const reference.
Also, C++11 introduced r-value references which complicate things even further. But that's a different topic.
These are the rules that I use:
for native types:
by value when they are input arguments
by non-const reference when they are mandatory output arguments
for structs or classes:
by const reference when they are input arguments
by non-const reference when they are output arguments
for arrays:
by const pointer when they are input arguments (const applies to the data, not the pointer here, i.e. const TYPE *)
by pointer when they are output arguments (const applies to the data, not the pointer)
I've found that there are very few times that require making an exception to the above rules. The one exception that comes to mind is for a struct or class argument that is optional, in which case a reference would not work. In that case I use a const pointer (input) or a non-const pointer (output), so that you can also pass 0.
If you want a copy, then pass by value. If you want to change it and you want those changes to be seen outside the function, then pass by reference. If you want speed and don't want to change it, pass by const reference.
Assuming we are running a compiled C++ binary:
Is passing around an int (e.g. function to function, or writing it into variables) slower than passing around structs/class objects like the following?
class myClass
{
int a;
int b;
char c;
vector d;
string e;
}
It depends on several factors, including the complexity of the copy-constructor and whether the compiler can do elision.
Any time something gets copied how long it takes is going to be a direct result of how big that thing is and what things its copy constructor does; obviously that class is larger than a single int, so it would be slower. If you pass a pointer or pass the thing by reference, there's no copy required and it takes the same amount of time
Passing a pointer or reference to an object around is the same as passing an integer around.
However, if you're passing actual objects (not pointers to them) around, you may end up with copies being made of the objects, which is expensive. A lot of the possible copies may get optimized away though, but it still happens.
Passing an instance of myClass around is slower than passing an int variable around, because the class encapsulates more than an int. Rather, you should ask whether passing around the various primitives constituting the member variables around is slower than passing a single object that wraps them all as one. The answer is no, the two methods should exhibit the same performance. There is no magic in a class: a class just associates data with functions, if you'd try to express this on your own without the C++ facilities you'd end up with the same performance -- or, as it may more like be -- a worse performance than C++ compilers already give you.
That said, C++ allows you to override the assignment operator for a given pair of types, and it also allows you to write your own copy-constructor such that an instance constructs in terms of another instance of the same class. These two are functions you write, and so the performance of the copy will depend on the performance of these functions. If you don't supply your own copy mechanism and you use the one C++ provides then the performance is optimal, in that the copy is done bit-wise. That is, each member simply itself gets copied.
First, a lot depends upon whether you are passing objects by reference or by value.
In C# and Java, you're always passing objects around by reference, but in C++, you can pass a copy of an object on the stack (i.e. pass-by-value). Doing this involves making a physical copy of the object in memory, which implies a pair of constructor/destructor calls (at least).
Passing an int can be done either by value or by reference. If you pass by value, you're copying an int type (let's say 32 bits) onto the stack. If you pass by pointer, you're copying an address (again, let's say 32 bits) onto the stack. There really isn't any difference in terms of stack usage. In the pass-by-reference case, the calling function will have to dereference the pointer to get access to the value of the int parameter, so there is going to be some additional code (and potentially reduced performance).
Passing an object (or struct) by value vs. reference is more interesting, because they may have very different memory footprints (depends upon the size of the class/struct).
It depends a lot on the members of your class.
Usually you supply a copy constructor, which copies all the needed data to the target instance of your class. The copy constructor is often optimized by the compiler, so there will be no difference between passing a class with 2 int fields, and just passing 2 ints.