定义流畅的界面会对性能产生影响吗?
我刚刚读了这个问题,这给我提出了另一个问题:
考虑这个类:
class Foo
{
public:
void setA(int a) { m_a = a; }
void setB(int b) { m_b = b; }
private:
int m_a, m_b;
};
哪个也可以使用“流畅的接口”方法编写:
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
指令是否会导致性能差异?
我应该打扰吗? (我的猜测是“不”)
I just read this question, which raises for me another question:
Consider this class:
class Foo
{
public:
void setA(int a) { m_a = a; }
void setB(int b) { m_b = b; }
private:
int m_a, m_b;
};
Which could also be written using the "fluent interface" method:
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;
};
Now, if I write the following code snippet:
int main()
{
Foo foo;
foo.setA(1);
foo.setB(2);
}
Is there a performance difference induced by the additional return
directives if I use the second implementation of the class ?
Should I bother ? (My guess is "no")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不知道你的编译器和优化器设置有没有?我认为没有什么可以阻止在您给出的确切情况下优化任何开销,但我可以想象为一个没有优化这种情况的深奥平台编写一个幼稚的、次优的编译器。
如果您认为它在特定情况下很重要,请测试它而不是假设。
I don't know, is there with your compiler and optimizer settings? I see nothing that prevents any overhead from being optimized away in the exact case you give, but I can imagine writing a naive, sub-optimal compiler for an esoteric platform which did not optimize this case.
If you think it matters in a given situation, test it instead of assuming.
由于方法是内联的,编译器应该能够看到返回值未被使用,并可能将其优化掉。
使用对您的项目设计最有意义的方式。然后,衡量性能,只有当性能不够好时,您才会考虑优化代码。
Since the methods are inlined, the compiler should be able to see that the return value is unused and possibly optimize it away.
Use whichever way makes the most sense for your project design. Then, measure the performance and only if it's not good enough would you consider optimizing the code.
我认为由于编译器优化,不会有任何差异。
I think there will be no difference due to compiler optimization.
如果使用第二种实现并且不需要设置函数的返回值,那么最好编写为这样
,以便编译器或静态分析器不会抱怨未使用返回值。
至于性能,与第一个实现相比,返回引用可能(我不确定)生成一两个额外的汇编指令,但可能没有任何“真正的”差异。
If the 2nd implementation is used and the return value of the set functions are not required, then it may be better to write as
so that the compiler or static analyzer does not complain that the return value is not used.
As for performance, returning the reference may (I am not sure) generate one/two additional assembly instructions compared to the 1st implementation, but may not any "real" difference.
通过定义类的方式,您不会发现两者之间有太大差异(如果有的话)。但是,如果您稍微修改一下设计,您将:
初始化
Foo1
:将比初始化
Foo2
更有效:在某些情况下,这不会成为问题。
您对 Fluent Interfaces 的另一个担忧是最终用户可能会错误地使用它们。在设计界面时,您希望将其设计为界面的用户很难破坏它。通过从每个 setter 返回一个引用,如果用户代码存储该引用,然后移动或释放该对象,则您将拥有一个悬空引用(甚至可能没有意识到)。
With the way you've defined the classes, you won't see much of a difference (if any) between the two. However, if you fix your design a bit, you will:
Initializing
Foo1
:will be far more efficient than initializing
Foo2
:In some cases, that won't be a concern.
An additional concern you have with Fluent Interfaces is the ability for the end-user to use them incorrectly. When designing an interface, you want to design it so that it is very difficult for the user of your interface to break it. By returning a reference from every setter, if the user-code stored that reference and then the object is moved or deallocated, you have a dangling reference (and may not even realize it).
这些性能差异从来都不重要。但是,通过实际应用程序的一些测量来证明我是错误的。
Those kinds of performance differences are never important. But, prove me wrong with some measurements of a real application.