Pergunta

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.

Foi útil?

Solução

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.

Outras dicas

Considering its a pseudocode, second one should be faster, since you don't need method1 and method2 to be called for each iteration.

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.

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.

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top