将类vs包括ptr作为成员变量的类实例继承一个类的性能影响是什么?

时间:2009-07-23 01:02:28

标签: c++

我在一个需要非常高性能的“A”课程中工作,并试图以任何方式解决这些问题。

如果我继承了这个新类“B”,那么“A”的内存配置文件应该增加那么多。

如果我在“A”中只将一个ptr包含在“B”中作为成员变量,那么我认为只要“B”在堆上(即new'd up)然后“ “除了新的ptr参考之外,它将保持尽可能小。还有其他我没有想到的东西吗?

对于我来说,继承“B”是最好的架构,但是将它作为成员变量坚持可能是更好的性能。

4 个答案:

答案 0 :(得分:3)

你担心微观优化。

您应首先进行基准测试,以确定实际瓶颈所在。他们很少会在你想到的地方!它们不太可能纯粹基于内存(堆或其他方式),更可能是基于算法或受系统中最慢组件(例如磁盘)约束。

答案 1 :(得分:3)

我相信继承在这里是最好的情况,但每种情况都不同,所以这里是每种选择的利弊。

继承

  • 通常需要虚拟析构函数,这会在删除对象时产生轻微的开销,并通过“指针”增加大小(所有虚拟对象都使用此指针,因此它更加清晰)
  • 允许您覆盖某个函数,以便即使将其强制转换为“基础”类,它也能正确地为您的对象操作。 (注意:这在调用函数时会调用很小的开销)
  • 班级的大小会增加'基数'的大小。
  • 任何非虚拟的“基础”函数都没有调用它们的开销。
  • 一般来说很清洁(只要继承有意义)

指向“基础”类

  • 每次要调用其中一个函数时(每个'base'函数都有开销),需要你取消引用指向'base'类的指针。
  • 无法正确覆盖函数(因此在'base'类上调用它们会调用基类容器中的函数)而不使用函数指针(这可能比虚函数更多开销)
  • 需要为两个分配单独分配,这些分配通常具有非常严重的性能和内存影响(分配很慢,通常分配与特定边界对齐,增加其大小,以及存储额外信息,因此块可以适当解除分配。)
  • 允许您不分配基类,在该实例中保存内存
  • 允许您在创建“基础”课程后更改“基础”课程。

真的,我认为作为一种优化,这可能是最不重要的项目之一。通常,对算法的一个小改动(例如添加早期转义)与这种优化相比会产生天文差异。应该指导这个决定的是该计划的结构,并且就此而言,我认为我能给你的最佳建议是:

大声说出,班级之间的关系,如果它的“A级 是B级”,那么你应该继承。如果您说“A类 B类”,那么您应该将A类指针保留在B类中。

答案 2 :(得分:2)

你有没有对此进行分析并确定这将是一个问题?或者你只是猜测?如果继承是更好和更清洁,那就这样做吧。之后,如果事实证明另一种方法可能更快,那么这样做,分析两者,并确定哪一种更快。

然而,我很困惑。继承事物不会增加类的大小,除了基类的那些成员。事实上,拥有一个指向基础并从基础继承的行为有着截然不同的行为!虚拟功能如何运作?

此外,大小不应该减慢你的程序。通过引用传递,并使用pointer containersmart pointer,您不应该看到性能损失,无论大小。

答案 3 :(得分:1)

从性能角度来看,您是正确的,而不是继承将减少类的大小并避免虚拟表查找。但是我相信你错过了设计课程的主要部分。你必须考虑类之间的关系。如果它使A的设计意义从B继承那么你应该这样做。也许A和B都应该重新启用接口?或者您可以使用合成,这意味着您拥有B,并委托给它。组合通常优于遗传。您需要了解自己的选择并评估您的选择,而不仅仅是表现。