吸气剂和二传手。有性能开销吗?

时间:2012-12-13 05:16:58

标签: c++ performance getter-setter

我的C ++项目中有一个粒子系统引擎,粒子本身只是没有函数的变量的结构。目前,通过直接访问其变量,从其父类(ParticleSystem)更新每个粒子(粒子)。 E.g。

particle.x += particle.vx;

然而,我正在讨论使用这样的getter和setter:

particle.setX( particle.getX()+particle.getVX() );

我的问题是:调用getter和setter是否有任何性能开销而不是直接数据访问?

毕竟,我确实有很多粒子需要更新......

4 个答案:

答案 0 :(得分:45)

当未进行优化时,Setter和getter的性能开销它们几乎总是在进行链接时间优化的编译器上进行优化。对于没有编译器的编译器,如果他们对函数体有所了解(即不仅仅是原型),它将被优化出来。

但是,您使用getter和setter是因为您可能希望获取或设置该变量以产生其他副作用。就像改变物体的位置一样,也会改变物理模拟中附近物体的位置或类似物。

最后,在优化代码的上下文中,getter和setter操作的开销非常小,除非代码很热,否则不值得担心。如果它很热,只需将getter或setter移动到头文件并内联就可以了。

总而言之,getter和setter非常值得轻微或不存在的开销,因为它允许您非常具体地指定对象可以发生和不可发生的事情,并且它还允许您编组任何更改。 / p>

答案 1 :(得分:14)

我对此有不同的看法,而不是之前的答案。

getters和setter表明你的类没有以有用的方式设计:如果你没有从内部实现中抽象出外部行为,那么首先使用抽象接口是没有意义的,你可能会以及使用普通的旧结构。

考虑一下您真正需要的操作。这几乎肯定是直接访问位置和动量的x-y和z坐标,你宁愿将它们视为矢量(至少在大多数计算中,这都与优化)。所以你想要实现一个基于矢量的接口*,其中基本操作是矢量加法,缩放和内积。不是组件访问;你有时也可能需要这样做,但这可以通过一个std::array<double,3> to_posarray()成员或类似的东西来完成。

当无法从外部访问内部组件xy ... vz时,您可以安全地更改内部实现,而无需在模块外部制作任何代码。这几乎是getter / setter的重点;然而,当使用这些时,你可以做的只有那么多的优化:任何真正的实现改变都不可避免地使得getter慢得多。
另一方面,您可以通过SIMD操作,外部库调用(可能在CUDA等加速硬件上)等来优化基于矢量的界面。像to_posarray这样的“批量获取器”仍然可以合理有效地实现,单变量setter不能。


*我的意思是mathematical sense中的向量,而不是std::vector

答案 2 :(得分:4)

如果获取和设置变得稍微复杂一些,那么Getters和setter可以让您的代码在将来更容易进化。大多数C ++编译器都足够智能inline这些简单的方法,并消除了函数调用的开销。

答案 3 :(得分:2)

这个问题可以有各种答案,但我把我的想法放在这里。

对于性能,简单的POD类型可以忽略成本。 但仍有成本,这取决于你返回的类型。对于粒子,没有太多数据。如果这是一个图像类(如OpenCV cv :: Mat)或3d数据(如VTK中的PolyData),则setter / getter处理指针/迭代器比实际数据更好,以避免内存分配问题。

当你想要模板化时,setter / getter对于避免不明确的类型转换非常有用。 setter / getter可以是一种访问私有/受保护成员的方法,这也允许您避免使用x作为变量的通用名称。更重要的是,setter / getter可以返回左值参考,允许你进行particle.getX() = 10.0 ;