2

假设一个类具有一个具有固定类型的对象的组件。有两种方法可以使组件成为类的属性。一种是使用指针指向该类型的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; ... };

可能会更上一层楼。性能差别大吗?非常感谢!

4

3 回答 3

4

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

正如评论中提到的,引用是另一种解决方案,它避免了指针可能发生的“我的指针指向垃圾”的问题[尽管有可能,有一些“创造力”来提出一个没有引用的场景有效,您不能在不将其设置为有效的情况下创建引用]。

性能:嗯,任何间接对象都需要多读一次内存。因此,如果您要存储一些非常基本的内容,例如整数,则将至少读取一个额外的内存来读取实际的指针/引用内容,以获取正确的对象。但是,对于比一个整数更复杂的对象,无论如何,其他事情往往是大部分时间。编译器肯定会优化,如果你对同一个引用/指针做几件事,它只加载一次指针,所以开销分散在许多对象上。[一旦编译,引用和指针几乎无法区分]。

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

于 2013-01-29T16:53:08.067 回答
2

让我们关注性能:

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

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

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

于 2013-01-29T16:57:01.200 回答