性能打击从C + +风格转换?

我是新来的C + +风格强制转换,我担心使用C ++风格强制转换会破坏我的应用程序的性能,因为我的中断服务程序中有一个实时关键的截止date 。

我听说有些演员甚至会抛出exception!

我想使用C ++风格强制转换,因为它会使我的代码更“健壮”。 但是, 如果有任何性能下降,那么我可能不会使用C ++风格的转换,而是花费更多的时间来testing使用C风格转换的代码。


有没有人做过任何严格的testing/分析来比较C ++风格演员的performance与C风格演员?

你的结果是什么?

你画什么结论?

如果C ++风格的转换可以在概念上被C风格的转换替代,那么就没有开销。 如果不能,就像dynamic_cast ,没有C等价物,你必须以这种或那种方式来支付成本。

作为一个例子,下面的代码:

 int x; float f = 123.456; x = (int) f; x = static_cast<int>(f); 

用VC ++生成相同的代码 – 代码是:

 00401041 fld dword ptr [ebp-8] 00401044 call __ftol (0040110c) 00401049 mov dword ptr [ebp-4],eax 

转换为引用时,唯一可以抛出的C ++types是dynamic_cast 。 为了避免这种情况,转换为一个指针,如果转换失败将返回0。

运行时唯一有额外成本的是dynamic_cast ,它具有无法直接用C风格转换的function。 所以你没有问题。

让自己放心的最简单方法是指示编译器生成汇编输出,并检查它生成的代码。 例如,在任何合理的编译器中, reinterpret_cast将完全消失,因为它意味着“盲目前进并假装数据是这种types的”。

为什么会有性能问题? 它们执行与C强制转换完全相同的function。 唯一的区别是,它们在编译时捕获更多的错误,并且在源代码中更容易search。

static_cast<float>(3)完全等价于(float)3 ,并且会生成完全相同的代码。

给定一个float f = 42.0f reinterpret_cast<int*>(&f)完全等价于(int*)&f ,并且会生成完全相同的代码。

等等。 唯一不同的是cast dynamic_cast ,可以抛出exception。 但是那是因为它做了C风格演员不能做的事情。 所以除非你需要它的function,否则不要使用dynamic_cast

假设编译器编写者是智能的,通常是安全的。 给定根据标准具有相同语义的两个不同expression式,通常假设它们将在编译器中被相同地实现是安全的。

糟糕 :第二个例子当然应该是reinterpret_cast,而不是dynamic_cast。 现在修复它。

好吧,为了清楚起见,下面是C ++标准所说的:

§5.4.5:

转换执行

  • 一个const_cast (5.2.11)
  • 一个static_cast (5.2.9)
  • 一个static_cast后跟一个const_cast
  • reinterpret_cast (5.2.10),或者
  • 一个reinterpret_cast后跟一个const_cast

可以使用显式types转换的转换符号来执行。 相同的语义限制和行为也适用。 如果一个转换可以用上面列出的多种方式解释,那么就使用列表中第一个出现的解释,即使这个解释产生的结果是不合格的。

所以,如果有的话 ,由于C风格演员实施的C + +转换,C风格演员应该更慢 。 (当然他们不是,因为编译器在任何情况下都会生成相同的代码,但比C ++风格的types转换更为合理)。

有四个C ++风格的转换:

  • const_cast
  • static_cast
  • reinterpret_cast
  • dynamic_cast

如前所述,前三个是编译时操作。 使用它们没有运行时间的损失。 它们是向编译器发送的消息,即以单向方式声明的数据需要以不同的方式访问。 “我说这是一个int* ,但让我来访问它,就好像它是一个char*指向sizeof(int) char s”或“我说这个数据是只读的,现在我需要将它传递给函数将不会修改它,但不会将该参数作为一个常量引用。

除了通过将数据转换为错误的types和缓冲数据(总是使用C风格转换的可能性)来破坏数据之外,这些转换最常见的运行时问题是实际声明为const数据可能无法转换为非const。 将const声明为非const的东西,然后修改它是未定义的。 未定义意味着你甚至不能保证崩溃 。

dynamic_cast是一个运行时构造,必须具有运行时成本。

这些演员的价值在于他们具体地说出了你想要演奏什么,从视觉上伸出来,并且可以用大脑死亡的工具进行search。 我会推荐使用它们来使用C风格的演员。

当使用dynamic_cast时,会在运行时进行一些检查,以防止你做一些愚蠢的事情(更多的GCC邮件列表 ),一个dynamic_cast的成本取决于有多less类受到影响,哪些类受到影响等。
如果你确定演员是安全的,你仍然可以使用reinterpret_cast

虽然我同意“在运行时只有一个额外的开销是dynamic_cast ”,但请记住,编译器可能存在一些差异。

我已经看到了一些针对当前编译器提出的错误,其中代码生成或优化略有不同,具体取决于您使用的是C风格还是C ++风格的static_cast

所以如果你担心,请检查热点的反汇编。 否则,当你不需要时,避免dynamic转换。 (如果closuresRTTI,则无论如何都不能使用dynamic_cast 。)

规范的事实是程序集,所以试试看看你是否有不同的逻辑。

如果你得到完全相同的组件,那就没有区别 – 不可能有。 唯一需要坚持使用旧的C语言转换的地方是纯粹的C例程和库,对于types转换而言,引入C ++依赖是没有意义的。

有一件事要注意的是,在一个体面大小的代码片段发生施放。 在我整个职业生涯中,我从来没有在逻辑上search过“所有演员”,而是倾向于search特定types的“A”,对“(A)”的search通常与像“static_cast <A>”。 使用更新的types,比如typesvalidation等,并不是因为它们使得search永远不会变得简单。