Getters和Setters.是否存在性能开销

Getters and Setters. Is there performance overhead?

本文关键字:性能 开销 存在 是否 Setters Getters      更新时间:2023-10-16

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

particle.x += particle.vx;

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

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

我的问题是:与直接访问数据相比,调用getter和setter是否会带来性能开销

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

Setter和getter在未进行优化时会产生性能开销它们几乎总是在进行链接时优化的编译器上进行优化。在没有的编译器上,如果他们了解函数体(即不仅仅是原型),就会对其进行优化。只需查找内联优化即可。

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

最后,在优化代码的上下文中,getter和setter操作的开销非常小,除非代码很热,否则不值得担心。如果它很热,只需将getter或setter移动到头文件并内联它就很容易了。
然而,在长期运行的科学模拟中,它可能会相加,但它需要数百万次调用。

总之,getter和setter非常值得花费少量或不存在的开销,因为它允许您非常具体地指定对象可以发生什么和不能发生什么,还允许您封送任何更改。

我对此的看法与前面的答案不同。

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

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

当内部组件xy。。。vz无法从外部访问,因此您可以安全地更改内部实现,而无需阻止模块外部的任何代码。这几乎就是进攻者/二传手的全部观点;然而,当使用这些时,你只能做这么多优化:任何真正的实现更改都不可避免地会使getter变得更慢。
另一方面,您可以通过SIMD操作、外部库调用(可能在CUDA等加速硬件上)等优化基于矢量的接口。像to_posarray这样的"批处理getter"仍然可以相当高效地实现,而单变量setter则不能。


*这里我指的是数学意义上的向量,而不是std::vector

Getters和setter允许您的代码在未来更容易地发展,如果获取和设置的任务稍微复杂一些的话。大多数C++编译器都足够聪明,可以内联那些简单的方法,并消除函数调用的开销。

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

就性能而言,对于简单的POD类型,成本大多可以忽略。但还是有成本的,这取决于你退货的类型。对于粒子,不可能有太多的数据。如果这是一个图像类(如OpenCV cv::Mat)或三维数据(如VTK中的PolyData),那么setter/getter处理指针/迭代器比实际数据更好,以避免内存分配问题。

当您想要对事物进行模板化时,setter/getter对于避免不精确的类型转换非常有用。setter/getter可以是访问私有/受保护成员的一种方式,这也允许您避免使用x作为变量的通用名称。此外,setter/getter可以返回一个Lvalue引用,该引用允许您执行particle.getX() = 10.0 ;

在这种情况下,计算的函数含义可能是:

void Particle::updatePosition(){x+=vx;y+=vy;}

或:

void Particle::updatePositionX(){x+=vx;}

然后:

particle.updatePositionX();