Reputation: 11773
My question comes from Proper way of designing functions with and without debug information in C++. I want to compare the efficiency of the following functions:
Function 1
bool my_func1(int arg1, int &output, std::vector<int> &intermediate_vec);
{
// do something
}
When I use this function, I will invoke it in the following way:
int arg;
int output;
std::vector<int> intermediate_vec;
my_func1(arg,output,intermediate_vec);
Function 2
bool my_func2(int arg1, int &output);
{
std::vector<int> intermediate_vec
return my_func1(arg1, output, intermediate_vec);
}
When I use this function, I will invoke it in the following way:
int arg;
int output;
my_func2(arg,output);
My question is: are these two functions of the same efficiency?
Upvotes: 1
Views: 126
Reputation: 22644
You can't tell almost anything about a functions's performance only from its signature. I can write the fastest and the slowest functions you can imagine with either one of these signatures.
In the second option you are adding a third parameter to the function. Do you need that parameter? If you need it, use that option. If you don't, use the first one.
Upvotes: 1
Reputation: 154047
The question is really rather silly; it really depends on the
use you make of intermediate_vec
. If it's part of the
interface, you need to make it an argument, and document its
pre- and post-conditions. If it's not part of the interface,
then making it an argument exposes internals of the function
which shouldn't be exposed. Efficiency (except programmer
efficiency) doesn't enter into it.
Beyond that, the only way to compare efficiency (at least in these sort of cases) is to measure.
Finally, if you are calling the function in a tight, frequently
executed loop, and the profiler shows that the construction of
intermediate_vec
(in version 2) is causing significant delays,
you might gain by using the first version, and moving the actual
vector outside the loop; the vector will probably reach its
maximum capacity fairly quickly, and after that, there will be
no further dynamic allocations. But this sort of change is
something that should only be undertaken in cases of absolute
necessity, when the program is not fast enough, and the
profiler shows that the allocations in creating the vector are
a significant reason for this. And I would stress the you
might; a lot still depends on how the compiler optimizes, and
how std::vector
is implemented.
Upvotes: 1
Reputation: 23650
The behavior of optimized functions is often very unpredictable. After all your functions may be inlined and show precisely the same performance characteristics. They might not be inlined or some optimization may fail in either case and any case could have worse performance. The only way to seriously figure things like that out it measuring performance with a reliable profiler in different settings.
Upvotes: 0
Reputation: 129524
This is one of those questions where the details are needed to answer exactly.
There should be very little difference especially ifthe compiler is able to inline the func1
or func2
to avoid the extra calling overhead (that is, the functions are declared in such a way that they can be "seen" by the compiler from the calling code).
The only time there would be a larger difference is if you can avoid constructing/destructing the intermediate_vec
- e.g. you are reusing the same one in a loop (but most likely you'd be "resetting" the vector in that case, which is the major part of destroying the vector).
How BIG the difference is, as a proportion of the total time, depends on exactly what do something
in func1
actually is doing.
However, like all performance questions, it's worth having a performance benchmark to compare the two. Make sure you compile it with the optimisation level of your actual code.
Upvotes: 2
Reputation: 8617
Since you are passing the vector as a reference (instead of creating temporary copies), any performance difference would be negligible (the compiler might even inline it to something equivalent - if not, you might incur some stack frame overhead).
It also depends on what do something actually does, and how these functions are getting called as well (i.e. is it some tight loop).
Best to profile and see.
Upvotes: 0