4

调用函数链有开销吗?例如,在以下 for 循环中:

for(int i = 0; i < n; i++)
{
  var=object.method1().method2().method3();
}

第一个比第二个效率低吗?

var = object.method1().method2();
for(int i = 0; i < n; i++)
{
  var.method3();
}

我关心的是知道函数调用/返回是否有开销,而不是函数在内部做什么。

谢谢。

4

5 回答 5

3

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.

于 2013-11-13T18:34:03.577 回答
2

考虑到它的伪代码,第二个应该更快,因为您不需要method1并且method2每次迭代都被调用。

于 2013-11-13T18:22:32.387 回答
1

如果你指的是方法级联,你会有这个:

class Object
{
public:
    Object& Method1()
    {
        // do something
        return *this;
    }

    Object& Method2()
    {
        // do something
        return *this;
    }

    Object& Method3()
    {
        // do something
        return *this;
    }    
};

所以像这样调用函数

obj.Method1().Method2().Method3();

在功能上等同于

obj.Method1();
obj.Method2();
obj.Method3();

简而言之,没有性能损失。这只不过是一个方便的成语。您面临的一个问题是,由于您被迫返回对 的引用this,因此您无法返回有意义的内容(例如这些函数的结果)。

如果您指的是方法链接

每个方法都必须返回一些对象,该对象具有链中跟随的相应方法:

class Object
{
public:
    std::vector<int>& Method1()
    {
        // do something
        return _vec;
    }
private:
    std::vector<int> _vec;
};

所以打电话

obj.Method1.size();

与调用相同

std::vector<int>& vec = obj.Method1();
vec.size();

同样,没有性能受到影响。

但是,如果您要更改Method1为通过复制而不是通过引用返回,则可能会影响性能(例如,如果实际复制了向量)。

不过,我认为您的问题措辞不佳。您的第二个示例每次迭代少调用 2 个函数,所以是的,它比每次迭代调用 3 个函数更有效。但是,我认为这并不是你真正要问的。

于 2013-11-13T18:26:28.343 回答
0

这实际上取决于您的编译器的智能程度,但假设编译器没有进行特殊优化,那么在您列出的示例中,您肯定最好使用第二个示例。在循环之前预先缓存 `object.method1().method2()' 的返回值绝对可以节省您的时间,因为您不必在每次迭代时进行这些函数调用或访问这些变量。

调用单个方法将比简单地访问局部变量产生更多开销,在您的示例中,您调用两个方法来访问单个返回值。

于 2013-11-13T18:24:05.237 回答
0

在第一个示例中,method1() 和 method2() 被调用了“n”次。在第二个示例中,method1() 和 method2() 仅被调用一次。如果“高效”是指“花费最少的时间”,那么第二个肯定更有效。

于 2013-11-13T18:25:19.840 回答