把指针或对象放在一个类中?

时间:2013-01-29 16:37:57

标签: c++ pointers optimization

假设一个类具有固定类型的对象的组件。有两种方法可以使组件成为类的属性。一种是使用指向此类型的ab对象的指针,另一种是直接使用该对象。使用指针时,我不需要包含组件类型声明的头文件,但只使用前向声明。而且它更具可扩展性。我的问题是:访问和使用它时的性能如何?现代编译器能否优化它以获得与直接使用相同或相似的性能?你决定采用什么策略?

一个愚蠢的例子

// Use pointer.
class A1 { ... };
class A2 { A1* a1; ... };
class A3 { A2* a2; ... };
class A4 { A3* a3; ... };
class A5 { A4* a4; ... };

// Direct use.
class B1 { ... };
class B2 { B1 b1; ... };
class B3 { B2 b2; ... };
class B4 { B3 b3; ... };
class B5 { B4 b4; ... };

可能更多关卡。性能有很大差异吗?非常感谢!

3 个答案:

答案 0 :(得分:4)

在决定设计时,我通常会忽略性能。是的,当然,您不希望以完全不合理的方式存储您的数据,但设计不应该考虑“如果我做X,那么访问此对象需要花费三个时钟周期吗?” - 它应该考虑“我需要做什么才能使这个软件正常工作,可维护”。

正如评论中所提到的,引用是另一种解决方案,它避免了指针可能发生的“我的指针指向垃圾”的问题[虽然它可能有一些“创造力”来提出一个参考的场景无效,如果不将其设置为有效的值,则无法创建引用。

性能:嗯,任何间接对象都需要再读一次内存。因此,如果要存储非常基本的东西,比如整数,则至少会有一个额外的内存读取来读出实际的指针/引用内容,以获得正确的对象。但是,对于比一个整数更复杂的对象,其他东西往往是大部分时间都需要的东西。编译器肯定会进行优化,这样如果对同一个引用/指针执行多项操作,它只会加载指针一次,因此开销会分布在许多对象上。 [编译后,引用和指针几乎无法区分]。

当有人询问虚函数的开销[与指针/引用的开销大致相同]时,我编写了一些测试代码来测量使用虚拟函数和非虚函数的性能。从内存来看,每次调用的差异小于1个时钟周期。 [因为处理器重叠了指令,所以开销有时少于一条指令]。

答案 1 :(得分:2)

让我们关注绩效:

  1. 指针始终是间接的,需要两个操作,一个获取地址,另一个取消引用地址以获取值。
  2. 对象内部对象由offset的编译时计算处理。 Asm代码直接从整个对象的开头有888 [eax]样式偏移。 888将在编译时计算。所以这只是一个访问值的操作。

答案 2 :(得分:1)

只需存储实例而不是指向对象的指针,除非由于某种原因需要指针,例如结构共享或其他自定义所有权语义。它通常会更快,它将简化您的程序,因为您不需要显式分配/释放指针。

(当然,您可以使用智能指针来阻止显式资源管理,但这会超过您跳过#include的目的,因为智能指针会拖拽很多模板代码。)