2

我刚读了这个问题,这给我带来了另一个问题:

考虑这个类:

class Foo
{
public:
  void setA(int a) { m_a = a; }
  void setB(int b) { m_b = b; }
private:
  int m_a, m_b;
};

也可以使用“fluent interface”方法编写:

class Foo
{
public:
  Foo& setA(int a) { m_a = a; return *this; }
  Foo& setB(int b) { m_b = b; return *this; }
private:
  int m_a, m_b;
};

现在,如果我编写以下代码片段:

int main()
{
  Foo foo;
  foo.setA(1);
  foo.setB(2);
}

return如果我使用该类的第二个实现,附加指令是否会导致性能差异?

我应该打扰吗?(我的猜测是“不”)

4

6 回答 6

4

如果我使用该类的第二个实现,额外的返回指令是否会导致性能差异?

我不知道,你的编译器和优化器设置有吗?在您给出的确切情况下,我没有看到任何可以防止任何开销被优化的东西,但我可以想象为一个没有优化这种情况的深奥平台编写一个幼稚的、次优的编译器。

如果您认为它在给定情况下很重要,请测试它而不是假设

于 2011-02-04T16:06:24.717 回答
0

使用您定义类的方式,您不会看到两者之间有太大差异(如果有的话)。但是,如果您稍微修改一下您的设计,您将:

class Foo1
{
public:
    Foo1(int a, int b) : m_a(a), m_b(b) {}
    void setA(int a) { m_a = a; }
    void setB(int b) { m_b = b; }
private:
    int m_a, m_b;
};

class Foo2
{
public:
    Foo& setA(int a) { m_a = a;  return *this; }
    Foo& setB(int b) { m_b = b;  return *this; }
private:
    int m_a, m_b;
};

初始化Foo1

Foo1 f(1, 2); // only constructor called

将比初始化更有效Foo2

Foo2 b; // constructor called
b.setA(1).setB(2); // 2 functions called

在某些情况下,这不会是一个问题。

您对 Fluent Interfaces 的另一个担忧是最终用户可能会错误地使用它们。在设计界面时,您希望将其设计为界面的用户很难破坏它。通过从每个设置器返回一个引用,如果用户代码存储了该引用,然后对象被移动或释放,那么您就有了一个悬空引用(甚至可能没有意识到它)。

于 2011-02-04T16:09:23.153 回答
0

这些性能差异从来都不重要。但是,用实际应用程序的一些测量来证明我是错误的。

于 2011-02-04T16:23:12.100 回答
0

我认为由于编译器优化,不会有任何区别。

于 2011-02-04T15:59:59.353 回答
0

如果使用第 2 种实现并且不需要 set 函数的返回值,那么最好写为

  (void) foo.setA(1);
  (void) foo.setB(2);

这样编译器或静态分析器就不会抱怨没有使用返回值。

至于性能,与第一个实现相比,返回引用可能(我不确定)生成一/两个额外的汇编指令,但可能没有任何“真正的”差异。

于 2011-02-04T16:07:59.650 回答
0

由于方法是内联的,编译器应该能够看到返回值未使用并可能优化它。

使用对您的项目设计最有意义的方式。然后,衡量性能,只有当它不够好时,你才会考虑优化代码。

于 2011-02-04T16:08:02.880 回答