RTTI有多昂贵? [英] How expensive is RTTI?

查看:188
本文介绍了RTTI有多昂贵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我明白,使用RTTI有一个资源命中,但它有多大?我所看到的任何地方都只是说RTTI是昂贵的,但没有人实际提供任何基准或定量数据来保证内存,处理器时间或速度。

I understand that there is a resource hit from using RTTI, but how big is it? Everywhere I've looked just says that "RTTI is expensive," but none of them actually give any benchmarks or quantitative data reguarding memory, processor time, or speed.

,RTTI有多昂贵?我可以在嵌入式系统上使用它,我只有4MB的RAM,所以每一点都是。

So, just how expensive is RTTI? I might use it on an embedded system where I have only 4MB of RAM, so every bit counts.

编辑:根据S. Lott的回答,它会更好,如果我包括我实际上在做什么。 我使用一个类来传递不同长度的数据,并且可以执行不同的操作,因此很难使用只有虚函数。看起来使用几个 dynamic_cast 可以通过允许不同的派生类通过不同的级别,但仍然允许他们完全不同的行为来补救这个问题。

As per S. Lott's answer, it would be better if I include what I'm actually doing. I am using a class to pass in data of different lengths and that can perform different actions, so it would be difficult to do this using only virtual functions. It seems that using a few dynamic_casts could remedy this problem by allowing the different derived classes to be passed through the different levels yet still allow them to act completely differently.

根据我的理解, dynamic_cast 使用RTTI,所以我想知道在有限系统上使用的可行性。

From my understanding, dynamic_cast uses RTTI, so I was wondering how feasable it would be to use on a limited system.

推荐答案

无论编译器如何,如果你能负担得起,你总是可以在运行时保存

Regardless of compiler, you can always save on runtime if you can afford to do

if (typeid(a) == typeid(b)) {
  B* ba = static_cast<B*>(&a);
  etc;
}

而不是

B* ba = dynamic_cast<B*>(&a);
if (ba) {
  etc;
}

前者仅涉及 std :: type_info ;后者必然涉及遍历继承树加比较。

The former involves only one comparison of std::type_info; the latter necessarily involves traversing an inheritance tree plus comparisons.

过去...像大家说的,资源使用是实现特定的。

Past that ... like everyone says, the resource usage is implementation specific.

我同意其他人的意见,提交者应该避免RTTI的设计原因。但是, 是使用RTTI的主要原因(主要是因为boost :: any)。记住,在常见的实现中知道它的实际资源使用是有用的。

I agree with everyone else's comments that the submitter should avoid RTTI for design reasons. However, there are good reasons to use RTTI (mainly because of boost::any). That in mind, it's useful to know its actual resource usage in common implementations.

我最近对GCC的RTTI进行了一系列研究。

I recently did a bunch of research into RTTI in GCC.

tl; dr:GTI中的RTTI使用可忽略的空间, typeid(a)== typeid(b) Linux,BSD和可能的嵌入式平台,但不是mingw32)。如果你知道你将永远在一个幸福的平台,RTTI是非常接近自由。

tl;dr: RTTI in GCC uses negligible space and typeid(a) == typeid(b) is very fast, on many platforms (Linux, BSD and maybe embedded platforms, but not mingw32). If you know you'll always be on a blessed platform, RTTI is very close to free.

粗糙的细节:

GCC喜欢使用特定的供应商中立C ++ ABI [1],并且总是将此ABI用于Linux和BSD目标[2]。对于支持此ABI和弱链接的平台, typeid()为每个类型返回一个一致且唯一的对象,甚至跨动态链接边界。你可以测试& typeid(a)==& typeid(b),或者只是依赖于事实,便携式测试 typeid )== typeid(b)实际上只是在内部比较指针。

GCC prefers to use a particular "vendor-neutral" C++ ABI[1], and always uses this ABI for Linux and BSD targets[2]. For platforms that support this ABI and also weak linkage, typeid() returns a consistent and unique object for each type, even across dynamic linking boundaries. You can test &typeid(a) == &typeid(b), or just rely on the fact that the portable test typeid(a) == typeid(b) does actually just compare a pointer internally.

在GCC的首选ABI中, / em>保存一个指向每类型RTTI结构的指针,尽管它可能不被使用。因此, typeid()调用自身应该只花费与任何其他vtable查找一样多(与调用virtual成员函数相同)

In GCC's preferred ABI, a class vtable always holds a pointer to a per-type RTTI structure, though it might not be used. So a typeid() call itself should only cost as much as any other vtable lookup (the same as calling a virtual member function), and RTTI support shouldn't use any extra space for each object.

从我可以做出的,GCC使用的RTTI结构(这些是 std :: type_info 的所有子类只保留每个类型的几个字节,除了名称。我不清楚的是,即使使用 -fno-rtti ,输出代码中是否存在这些名称。无论哪种方式,编译的二进制文件的大小的变化应该反映运行时内存使用的变化。

From what I can make out, the RTTI structures used by GCC (these are all the subclasses of std::type_info) only hold a few bytes for each type, aside from the name. It isn't clear to me whether the names are present in the output code even with -fno-rtti. Either way, the change in size of the compiled binary should reflect the change in runtime memory usage.

一个快速的实验(使用GCC 4.4.3在Ubuntu 10.04 64位)表明 -fno-rtti 实际上将增加了一个简单测试程序的二进制大小几百个字节。这在 -g -O3 的组合中始终如一。我不知道为什么尺寸会增加;一个可能性是GCC的STL代码在没有RTTI的情况下表现不同(因为异常不起作用)。

A quick experiment (using GCC 4.4.3 on Ubuntu 10.04 64-bit) shows that -fno-rtti actually increases the binary size of a simple test program by a few hundred bytes. This happens consistently across combinations of -g and -O3. I'm not sure why the size would increase; one possibility is that GCC's STL code behaves differently without RTTI (since exceptions won't work).

[1]称为Itanium C ++ ABI, =http://www.codesourcery.com/public/cxx-abi/abi.html> http://www.codesourcery.com/public/cxx-abi/abi.html 。名称是令人困惑的:名称指的是原始的开发架构,尽管ABI规范工作在很多架构,包括i686 / x86_64。 GCC内部源代码和STL代码中的注释将安腾称为新ABI,与之前使用的旧ABI相反。更糟的是,新/ Itanium ABI是指通过 -fabi-version 可用的所有 旧ABI早于此版本。 GCC在3.0版本中采用了安腾/版本/新ABI;

[1] Known as the Itanium C++ ABI, documented at http://www.codesourcery.com/public/cxx-abi/abi.html. The names are horribly confusing: the name refers to the original development architecture, though the ABI specification works on lots of architectures including i686/x86_64. Comments in GCC's internal source and STL code refer to Itanium as the "new" ABI in contrast to the "old" one they used before. Worse, the "new"/Itanium ABI refers to all versions available through -fabi-version; the "old" ABI predated this versioning. GCC adopted the Itanium/versioned/"new" ABI in version 3.0; the "old" ABI was used in 2.95 and earlier, if I am reading their changelogs correctly.

[2]我找不到任何资源列表 std :: type_info 平台的对象稳定性。对于我可以访问的编译器,我使用以下: echo#include< typeinfo> | gcc -E -dM -x c ++ -c - | grep GXX_MERGED_TYPEINFO_NAMES 。此宏控制GCC的STL中的 operator == for std :: type_info 的行为,从GCC 3.0开始。我确实发现mingw32-gcc遵循Windows C ++ ABI,其中 std :: type_info 对象对于跨DLL的类型不是唯一的; typeid(a)== typeid(b)调用 strcmp 我推测在单程序嵌入式目标,如AVR,其中没有代码链接, std :: type_info 对象总是稳定的。

[2] I couldn't find any resource listing std::type_info object stability by platform. For compilers I had access to, I used the following: echo "#include <typeinfo>" | gcc -E -dM -x c++ -c - | grep GXX_MERGED_TYPEINFO_NAMES. This macro controls the behavior of operator== for std::type_info in GCC's STL, as of GCC 3.0. I did find that mingw32-gcc obeys the Windows C++ ABI, where std::type_info objects aren't unique for a type across DLLs; typeid(a) == typeid(b) calls strcmp under the covers. I speculate that on single-program embedded targets like AVR, where there is no code to link against, std::type_info objects are always stable.

这篇关于RTTI有多昂贵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆