C ++代码比它的C等价慢?

时间:2012-09-11 21:26:06

标签: c++ c performance latency

C ++编程语言有哪些方面,其中代码比同等的C语言慢?显然,这将排除虚拟功能和vtable功能等OO功能。

我想知道,当你在延迟关键领域进行编程时(并且你不担心OO功能)是否可以坚持使用基本的C ++或者C会更好吗?

7 个答案:

答案 0 :(得分:5)

C或C ++语言标准中没有任何内容指定任何构造的速度(C ++确实指定了应用于容器的某些操作的时间复杂度,但这超出了您的问题的范围)。为给定构造生成的代码的速度取决于用于编译它的编译器,以及它运行的系统。

对于具有相同语义的有效C和有效C ++的给定代码构造,没有基本理由为什么要比另一个更快。但如果编译器的开发人员更加聪明,那么很可能会比另一个更快。

答案 1 :(得分:3)

这取决于你所说的“等价物”。如果将C的stdio.h与C ++的iostream进行比较,stdio.h操作通常会更快(在某些情况下会快得多)。但是,如果您正在讨论用C ++子集编写的代码也可以编译为有效C,那么生成的机器代码可能会完全相同。

答案 2 :(得分:3)

举个例子,C ++缺少关键字restrict。正确使用,有时允许编译器生成更快的代码。

  • 在实践中很少见到restrict的好处,但它确实发生了,
  • 在很多情况下,C ++或C编译器可以推导出(在内联之后)restrict的必要条件,并相应地采取相应行动,即使关键字未被使用,
  • 同时也是C编译器的C ++编译器可能会提供restrict__restrict作为扩展。

但偶尔(或在某些域中很常见),restrict是一个真正良好的优化,我被告知是仍然使用Fortran的原因之一。这肯定是C和C ++中严格别名规则的原因之一,它为restrict提供了与更有限的环境相同的优化机会。

您是否“计算”这取决于您认为“等效代码”的程度。 restrict永远不会改变有效使用它的程序的含义 - 编译器可以自由地忽略它。因此,描述使用它的程序(对于C编译器的眼睛)和没有(对于C ++)的程序是“等效的”并不是一个延伸。带有restrict的版本需要更多(可能只是稍微多一点)程序员的努力来创建,因为程序员在使用之前必须确保它是正确的。

如果你的意思是,是否有一个程序是有效的C和有效的C ++,并且在两者中具有相同的含义,但是实现在某种程度上受到C ++标准的约束,使它比C实现运行得慢,那么我很漂亮确定答案是“不”。如果你的意思是,在标准C中是否有任何可能的性能调整,但在标准C ++中没有,那么答案是肯定的。

您是否可以从调整中获得任何好处是另一回事,无论您是通过两种语言提供的不同优化同等数量的工作获得更多好处还是另一项优势,以及是否有任何优势足以建立基础你选择的语言还是另一种。在C和C ++代码之间可以很容易地进行互操作,所以如果你有任何理由喜欢C ++,那么就像改变你喜欢的编码方式的任何优化一样,切换到C通常是你在探查器讲述时要做的事情。你的功能太慢,而不是之前。

另外,我试图以一种方式说服自己是否存在异常可能会导致性能损失,假设您从不使用任何具有非平凡析构函数的类型。我怀疑在实践中它可能(并且这与“不支付你不使用的东西”原则相矛盾),如果只是因为否则gcc没有-fno-exceptions 。 C ++实现使成本降低得非常低(而且主要是在rodata中,而不是代码),但这并不意味着它是零。延迟关键代码可能也可能不是二进制大小关键代码。

同样,它可能取决于“等效”代码的含义 - 如果我必须使用非标准编译器(例如g++ -fno-exceptions)编译我所谓的“标准C ++程序”,以便“证明“C ++代码与C一样好,然后在某种意义上说C ++标准让我付出了代价。

最后,C ++运行时本身具有启动成本,这与“相同”程序的C运行时启动成本不一定相同。你通常可以通过删除你并不严格需要的东西来降低成本。但这是努力,实现不一定每次都完全适合你,所以它不是严格是真的,在C ++中你没有为你不使用的东西买单。这是一般原则,但实现它是一个实施质量问题。

答案 3 :(得分:2)

与许多C程序员喜欢的想法相反,人们通常可以在C ++中编写更严格和更快的代码,而不必牺牲大量的设计。

我无法想到C ++中的任何内容都比C中的对手慢。虚拟函数不排除。

答案 4 :(得分:1)

延迟关键是否意味着尽可能快或者它只是意味着一切都必须在可预测的时间内运行

如果是第二种情况,那么在可预测的时间内没有运行的唯一事情是newdeletetry/catch。在嵌入式编程中,有一些指令可以避免这种调用。在其他情况下,特别是在C ++ 11中,您可能会注意到某些事情更快(std :: sort比C的sort()更快)并且有些事情稍微慢一点。

但是你比C ++获得的是更高的抽象级别,你没有得到C风格的错误(比如典型的malloc()没有相应的free()

答案 5 :(得分:0)

C ++中没有代码,它在C中的直接等价物更快 - 或者实际上更易于维护。

答案 6 :(得分:0)

如果您使用的是C和C ++的交叉语言,那么使用C编译器和C ++编译器编译代码时的性能差异纯粹是一个实施质量问题;没有理由比另一个更快。

当然,在现实世界中,如果你正在使用C ++,你可以使用C ++在C和C ++的交叉点上使用不同的习语附加功能进行编程。 /或者比你在C中所做的那样。相反,如果你使用C,你至少会使用与C ++中使用的不同的习语,你也可能正在使用现代C语言的其他功能。像史蒂夫提到的那样,C ++不具有restrict关键字,或者VLA或指向VLA类型的指针,或复合文字。这些功能可能在某些情况下会带来重大的性能优势,但根据我的经验,大多数选择C over C ++的人都不会这样做。

在我看来,主要区别在于成语。在C中,通过将下一个/ prev指针直接放在保存在列表中的结构中而不是为列表和列表节点使用单独的包装器对象来创建链接列表是惯用的。在C中,它是直接在字符串的元素上迭代作为字符数组的惯用语。在C中,尽可能使用完全存在于自动存储中的对象而不是分配动态存储,这是惯用的。等等。这些惯用差异是C代码比C ++更快更轻的主要方式。

当然,如果你愿意,你可以在C ++中使用相同的习语,因为大多数C语言所需的大多数语言结构都存在于C和C ++的交集中。然后,您还可以在适当的时候使用C ++的其他功能。但是你要编写非惯用的C ++代码,你可能会受到其他C ++程序员的批评......