【问题标题】:RTTI Overhead in C++C++ 中的 RTTI 开销
【发布时间】:2011-07-21 10:55:48
【问题描述】:

在 C++ 程序中启用 RTTI 的内存/性能开销是多少?
任何人都可以在 RTTI 机制的内部实现和相关开销之间进行一些说明吗?
我确实了解如何通过typeiddynamic_cast 使用RTTI,我想知道的是运行时如何跟踪这些信息以及它是如何产生开销的内部实现细节?

【问题讨论】:

  • 如果你需要dynamic_cast的功能,那不是开销。否则你会怎么做“更便宜”?
  • @Bo Persson:问题不是因为我知道或者有/将会有一种“更便宜”的方式,而是问题是要了解内部 RTTI 的实现方式并了解明显的间接费用是多少。我认为当我们使用编程语言的某些方面时,对幕后发生的事情产生好奇是很自然的。
  • 我只是反对你称之为开销。如果它是您需要的功能,那么它不是开销。 :-) 如果您不需要它,请不要使用它。
  • @Bo Persson:同意开销点!也许我应该说“成本”而不是“开销”:)

标签: c++ casting rtti


【解决方案1】:

启用 RTTI 通常只会带来很小的开销。通常的实现带有一个指向对象 vtable 中类型信息结构的指针。由于无论如何都必须构造 vtable,因此额外的时间很少 - 这就像在类中添加另一个虚函数一样。

typeid 因此相当于调用虚函数。 dynamic_cast 较慢 - 它需要遍历继承层次结构来进行强制转换。过于频繁地调用dynamic_cast可能成为性能瓶颈。 '可以' 我的意思是它通常不会……

由于 typeinfo 结构需要存储在某个地方,因此可执行文件大小略有膨胀。在大多数情况下,它是不相关的。

【讨论】:

  • 正如 Bo Persson 评论的那样,重要的是要注意,如果你想要 typeiddynamic_cast 这不是开销:它是实现功能所必需的。此外,由于 VTable 往往是在运行时仅分配一个指针的常量结构,因此开销可能为零。
  • 谢谢!您的回答最好地总结了 RTTI 的“开销”或更确切地说是“成本”。
【解决方案2】:

请阅读this document中的相应部分。

总结一下:

  • typeid(5.3.7):找到vtable,通过那个找到最衍生的类对象,然后从那个对象的vtable中提取type_info。和函数调用相比还是很慢的;

  • dynamic_cast(5.3.8):按照上面的方法找到type_info,然后判断是否可以转换,然后调整指针。运行时成本取决于所涉及的两个类在类层次结构中的相对位置。这些天向下和交叉转换非常缓慢(尽管here 你可以找到关于可能(但受限)的动态转换的恒定时间实现的文章)。

【讨论】:

  • 诚挚邀请您在回答中总结“适当的部分”。这样,如果链接失效,您的答案就不会一文不值。
  • 是的,先生! (虽然标准化委员会的文件很少死)
  • TR 实际上说“与函数调用相比非常慢”,而不是“虚函数调用”。
  • 无论哪种方式,答案仍然是“使用函数调用”而不是“到 a”
【解决方案3】:

首先,如果不指定编译器和版本,则无法准确说明涉及多少开销,因为它是一个实现细节。也就是说,众所周知,在某些编译器中,dynamic_cast 会搜索类层次结构,通过字符串比较来匹配类名。

【讨论】:

    【解决方案4】:

    我想知道 RTTI“开销”的想法是从哪里得到的?

    我在网上看到,为了提供 R.T.T.I.,一些(早期的)C 到 C++ 预处理器或翻译器,类似的工具(GObject、QT、Objective-C,不确定)和其他程序。朗格生成一些“幕后”代码,这确实会在内存和速度方面产生一些“开销”。

    我最终读到,“开销”减少了,而且很多时候被认为是微不足道的。

    也许您想在没有 R.T.T.I. 的情况下使用汇编或“普通 C”编程。开销,比 C++ 容易得多

    【讨论】:

    • 来自维基百科:“在工程中,某些方法或组件对系统提出了特殊要求。满足这些要求所必需的额外设计功能称为开销。”。问题是“在 C++ 程序中启用 RTTI 的内存/性能开销是多少?”。至少可以说是相关的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 2023-03-05
    • 2010-10-29
    • 2010-12-31
    • 2011-10-04
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多