How to pass a std::shared_ptr<Resource> to a function? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Should I pass a shared_ptr by reference?
Passing smart pointers as arguments
Should I pass it by value or by constant reference? I have read numerous rules of thumb on whether to pass a copy constructible object by value or by constant reference. Such as:
pass objects by constant reference and built in types by value (except function objects)
pass by value unless size of the object (including dynamic memory) is less than 2 * size of a double.
Could you explain how do these rules apply to std::shared_ptr<Resource>? I understand that the object is probably very small, likely a pointer and a reference counter, but it is still an object. What is the best practice here?

Perhaps the most important concern (with regards to performance) is that creating a copy of a std::shared_ptr<...> (such as happens when you pass by value) requires an interlocked increment of a reference count. Or maybe some other form of synchronization like a critical section, depending on implementation. Such a cost could be significant in a multithreaded program.
Passing by reference is almost certain to be a better choice. It's main drawback (or is this only with boost::shared_ptr<...>?) is that shared_ptr<...> offers only the standard thread safety guarantee: access to a single shared_ptr<...> must be guarded (e.g. by a mutex) unless all accesses are only to const methods. In a multithreaded situation, passing around const references to shared_ptr<...>s may make it more difficult to ensure proper synchronization.
In a single threaded program, it probably doesn't make much of a difference.

Related

Is it faster to return a value or to use pointer parameters [duplicate]

This question already has answers here:
How to "return an object" in C++?
(8 answers)
Closed 9 years ago.
I wanted to know if it is faster to normally return a value from a function or to use a pointer as a parameter and pass the value to that pointer.
In different common ABIs, return-by-value for large (not fitting in registers) objects is implemented through a pointer anyways. The caller reserves the space, and passes a pointer to the callee, that uses that pointer to create the object in place.
With modern Compilers and C++11 returning by value is fastest in many cases: Want Speed? Pass by Value. (Archive)
I will assume we're talking about C++11 here, since it's been 2.x years already.
Start by returning your object by value: move semantics, (N)RVO can kick in and generate really fast code that is really easy to read. However, if you profile your code and find that this particular function is a bottleneck, consider using a reference as an "out-parameter." This may in fact be faster than using a pointer, as the compiler has more flexibility with how to represent a reference. The ISO standard for C++ does not dictate that references require storage, so the compiler is free to make the reference a literal alias of the other memory location, using effectively zero bytes of overhead.
All in all though, write the cleanest code first, and then measure it. People underestimate just how much optimization the compiler can do for you if you just return your (movable) objects by value.
Pointer is 4 or 8 bytes long depending on the architecture.
If your value is less that that in size, it might be faster to pass values.
If you have large objects and copy constructors, then more memory will be copied and passing that kind of parameters would be more expensive.
But... compiler optimizations, memory alignment, and other sorcery, might need you to directly investigate this in YOUR case.
In return by value case, assume the caller has an object to pass the compiler will crate a copy of that argument which is more or less equivalent to the cost of pass by reference. So from performance point of view either solutions seems equivalent.

C++ parameter type and efficiency [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Basing on what I've gathered from compiler writers value types are much preferred to references/pointers in terms of efficiency.
This comes from a fact that a values types are easier to reason about when you don't have to care about aliasing, externally changed memory (which the pointer refers to), cost of pointer dereference, and such things. I have to say that while I understand such concerns I still have a few questions regarding specific cases.
Case #0
void foo(const float& f)
Okay, we have a reference here, but it's constant! Sure we have a constant view (ref) of it, so externally it might be change, but it could only happen in multithreaded world and I am not sure if compiler has to take it into consideration at all if there are no synchronization primitives used. Obviously if internally we used another pointer/reference to any float variable we might be at risk of modifying the f parameter. Can compiler treat this parameter as safe (assuming we don't use any ref/ptr to float internally)?
Case #1
void foo(vector<int> f)
Talking from a C++11/14 programmer perspective I know that the vector can be safely moved into the function. As we all know, internally the container holds a pointer to an array. Will the compiler treat the pointer as safe (no externally modifications) as we just got a copy of vector, so we are the only owners of it?
In other words: is a copied object treated as a safe one (because logically we make a clone of the object), or the compiler is not allowed to make such assumptions and any ptr/ref member has to be treated as potentially dangerous as the copy ctor/op might not have made a proper copy. Shouldn't the programmer be responsible for handling shared resources when copying them?
Bottomline:
Do constant pointers/references and copied complex objects are generally slower than copies of primitives, and thus should be avoided as much as possible in performance critical code; or they are only slightly less efficient and we shouldn't fret about it?
As general rules in modern C++:
For (cheap to copy) primitive types, like int, float or double, etc., if it's an input (read-only) parameter, just pass by value:
inline double Square(double x)
{
return x*x;
}
Instead, if the type of the input parameter is not cheap to copy, but it's cheap to move, e.g. std::vector, std::string, etc., consider two sub-cases:
a. If the function is just observing the value, then pass by const reference (this will prevent useless potentially expensive deep-copies):
double Average(const std::vector<double> & v)
{
.... // compute average of elements in v (which is read-only)
}
b. If the function is taking a local copy of the parameter, then pass by value, and std::move from the value (this will allow optimizations thanks to move semantics):
void Person::SetName(std::string name)
{
m_name = std::move(name);
}
(Started as a comment but it wouldn't fit.)
Case #0 has already been discussed to death, for example:
Is it counter-productive to pass primitive types by reference?
which is already a duplicate of two other questions. In particular, I find this answer a good answer to your case #0 as well. Related questions:
Is it better in C++ to pass by value or pass by constant reference?
Reasons to not pass simple types by reference?
is there any specific case where pass-by-value is preferred over pass-by-const-reference in C++?
"const T &arg" vs. "T arg"
How to pass objects to functions in C++?
Case #1 is unclear to me: Do you need a copy or do you want to move? There is an enormous difference between the two and it is unclear from what you write which one you need.
If a reference suffices but you do a copy instead, you are wasting resources.
If you need to make a deep copy then that's all there is to it, neither references nor moving will help.
Please read this answer and revise case #1.
Case #0
No - It may be externally modified:
void foo(const float& f) {
..use f..
..call a function which is not pure..
..use (and reload) f..
}
Case #1 ... Will the compiler treat the pointer as safe (no externally modifications) as we just got a copy of vector, so we are the only owners of it?
No - it must be pessimistic. It could be taught to rely on an implementation but in general, it has no reasonable way of tracking that pointer through all possible construction scenarios for arbitrary construction to verify it is safe, even if the implementations were visible.
Bottomline:
Cost of allocation and copying containers tend to be much greater than the cost of the loads and stores -- depends on your program, hardware, and implementation!
Passing small objects and builtins by reference doesn't mean an optimizer must treat it as a reference when the implementation is visible. E.g. If it sees the caller is passing a constant, it has the liberty to make the optimization based on the known constant value. Conversely, creating a copy can interfere with the ability to optimize your program since complexity can increase. Fretting over whether or not to pass this trivial/small type by value is an old micro-optimization. Copying a (non-SSO) string or vector OTOH can be huge in comparison. Focus on the semantics first.
I write tons of performance critical code and pass almost everything by (appropriately const-qualified) reference -- including builtins. You're counting instructions and speed of memory at that point (for your parameters), which is very low in desktop and portable computers. I did plenty of testing on desktops and notebooks before settling on that. I do that for uniformness - you don't need to worry about the cost of introducing the reference (where overhead exists) outside embedded. Again, the cost to make unnecessary copies and any necessary dynamic allocations tend to be far greater. Also consider that objects have additional construction, copy, and destruction functions to execute -- even innocent looking types can cost much more to copy than to reference.

Transmit parameter by value or by reference in C++? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pass by reference more expensive than pass by value
I want to know which is better, sending parameters by value or by reference in C++. I heard that there are cases where sending by value is faster than sending by reference. Which are these cases?
Thanks
As a general rule, you should pass POD types by value and complex types by const reference.
That said, a good place where you pass complex types by value is where you would need a copy of the object inside the function anyway. In that case, you have two choices:
pass the argument as a const reference and create a local copy inside the function
pass the argument by value (the compiler creates the local copy).
The second option is generally more efficient. For an example, see the copy&swap idiom.
The obvious case is when the parameter is equal to or smaller than a pointer in size and trivial to copy -- then you would pass by value. However, this is a age-old discussion and quite a long answer is required to answer it correctly for a given architecture. There are also many corner cases (e.g. RVO).
There's more to the question than speed -- semantics should be your first priority.
See also: Is it better in C++ to pass by value or pass by constant reference?

Returning vs. using a reference parameter [duplicate]

This question already has answers here:
Which is more efficient: Return a value vs. Pass by reference?
(7 answers)
Closed 1 year ago.
This is really bugging me, coming from a C# background.
Sometimes, I see functions written like this:
int computeResult();
This is what I'm used to. But then I see them written like this:
void computeResult(int &result);
I find this strange. What benefits does the second method have over the first, if any? There must be something, since I see it all the time.
There are two common reasons for such non-const reference parameters:
You may need multiple "out" parameters in a function, and using reference parameter(s) allows for this.
Your object may be expensive to copy, and so you pass in a reference that will be mutated rather than returning an object that may get copied as part of the return process. Expensive-to-copy objects may include standard containers (like vector) and objects that manage heap memory where an allocation-copy-deallocate sequence would occur. Note that compilers are getting really good at optimizing away these copies when possible and so this reason has less import than it used to.
EDIT: I should clarify that even in C++ the specific example you've provided with a single builtin type reference parameter is pretty atypical. In such cases a return value is almost always preferred.

Pass by Reference v. Pass by Pointer -- Merits? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
When pass-by-pointer is preferred to pass-by-reference in C++?
Are there benefits of passing by pointer over passing by reference in C++?
How to pass objects to functions in C++?
Hi all,
I'm working to develop a large object oriented c++ application framework as part of my chemical engineering graduate research.
I find that many of my functions take pointers to custom objects or STL objects. I find that in terms of writing code, this makes it harder to access functions or variables stored within.
Aside from simplicity, though, is there any advantages/disadvantages to passing by reference v. passing by pointer?
If there is an advantage to one over the other, I'll probably look to refactor my code to uniformly use whatever approach is optimal. If there isn't I may still refactor to consistently use pass by reference for readability (i.e. not having to dereference)
Again I want to make the best decision as my framework is already 40+ files large, so I want to implement as uniform structure as I can, as early as I can, and with whatever the optimal method is.
Thanks in advance!
The main difference is that a reference cannot be NULL (at least not without some malicious programming). For syntactical sugar and when an argument is required, I'd pass by reference. If I had a situation where the argument were optional, I'd pass by pointer.
There are always exceptions. If it conforms to the current style, or due to things I have to do with it, it may be more convenient to have it as a pointer.
Prefer pass by reference. If for nothing else I do it because a reference simply can't be NULL. It puts an end to so many stupid bugs, debates, contract checks, memory responsibility questions, etc ...
FYI this was asked in a slightly diff way earlier today:
When to pass by reference and when to pass by pointer in C++?
Canonical advice is "pass by ref to const unless a v good reason for another choice".
If your choice is pointers vs. references, use references. They have all the advantages of pointers without the danger of dereferencing an uninitialized pointer.
And don't worry too much about implementing a uniform approach early-- in this case it really isn't difficult to go back and forth between the two (one function at a time) even when the code base is large.
Personally I like passing by pointer because it offers some level of consistency in my code. I automatically know that my object Foo is a pointer. The same would apply with a reference so be sure to pick one and stick with it.
While I like references, there are a few common cases where you can't use them:
You want to store an object reference/pointer in a member variable but don't want to require that object in your class constructor
You want to store an object reference/pointer in a member variable and change the instance at runtime
You want make an object parameter to a method or function optional
In my view, having a mix of references and pointers is pretty ugly, so I prefer pointers.