Reputation: 85
Is there overhead in calling function chains? For example, in the following for loop:
for(int i = 0; i < n; i++)
{
var=object.method1().method2().method3();
}
Is the first less efficient then the second?
var = object.method1().method2();
for(int i = 0; i < n; i++)
{
var.method3();
}
My concern is to know wether there is overhead with function calling/returning, and not so much what the function does on the inside.
Thanks.
Upvotes: 5
Views: 1075
Reputation: 14705
Your two snippets are not functionally equivalent.
Your original question was tagged c++/Java so lets go with that. A functional language might treat this differently.
In general the second version is quicker because the method1().method2()
only needs to be called once. In C++ and Java the compiler has a really hard time figuring out if the calls method1().method2()
has any side effects. Consider a method that takes user input for instance.
If the methods has side effects the compiler cannot do any optimizations to the number of calls in var = object.m1().m2().m3()
.
The chaining itself does not produce any overhead.
Upvotes: 3
Reputation: 15872
If you are referring to method cascading, you'd have this:
class Object
{
public:
Object& Method1()
{
// do something
return *this;
}
Object& Method2()
{
// do something
return *this;
}
Object& Method3()
{
// do something
return *this;
}
};
So calling the functions like this
obj.Method1().Method2().Method3();
Is functionally equivalent to
obj.Method1();
obj.Method2();
obj.Method3();
In short, there is no performance hit. It is nothing more than a convenience idiom. The one problem you face is that, since you are forced to return a reference to this
, you cannot return something meaningful (e.g. the result of these functions).
If you are referring to method chaining:
Each method must return some object that has the corresponding method that follows in the chain:
class Object
{
public:
std::vector<int>& Method1()
{
// do something
return _vec;
}
private:
std::vector<int> _vec;
};
So calling
obj.Method1.size();
Is identical to calling
std::vector<int>& vec = obj.Method1();
vec.size();
So again, there is no performance hit.
However, if you were to change Method1
to return by copy instead of by reference, it is possible to have a performance hit (e.g. if the vector is actually copied).
Though, I think you worded your question poorly. Your second example has 2 less function calls per iteration, so yes, it will be more efficient than calling 3 functions per iteration. But, I don't think that is really what you were asking about.
Upvotes: 1
Reputation: 3156
In the first example, method1() and method2() are being called "n" times. In the second example, method1() and method2() are only being called once. If by "efficient" you mean "takes the least amount of time", then the second one is definitely more efficient.
Upvotes: 0
Reputation: 4962
It really depends on how smart your compiler is, but assuming there is no special optimization happening on the compiler's behalf, in the example you listed you'd definitely be best off with your second example. Pre-caching the return value of `object.method1().method2()' prior to your loop will absolutely save you time as you won't have to make those function calls or access those variables each time you iterate.
Calling a single method will have more overhead than simply accessing a local variable, and in your example you're calling two methods to access a single return value.
Upvotes: 0
Reputation: 223207
Considering its a pseudocode, second one should be faster, since you don't need method1
and method2
to be called for each iteration.
Upvotes: 2