是否值得用C语言编写部分代码而不是C ++作为微优化?

时间:2010-10-22 15:32:21

标签: c++ c performance micro-optimization

我想知道现代编译器及其优化是否仍然值得用C而不是C ++编写一些关键代码以使其更快。

我知道C ++可能导致在复制的情况下性能不佳,而它们可以通过引用传递,或者当编译器自动创建类时,通常使用重载运算符和许多其他类似情况;但是对于一个知道如何避免这一切的优秀C ++开发人员来说,仍然值得用C语言编写代码以提高性能吗?

5 个答案:

答案 0 :(得分:18)

我会同意很多评论。在C ++中有意支持C语法(仅在C99中有分歧)。因此,所有C ++编译器都必须支持它。事实上,我认为很难找到任何专用的C编译器。例如,在GCC中,无论代码是C还是C ++,您实际上最终都会使用相同的优化/编译引擎。

真正的问题是,编写纯C代码和在C ++中编译是否会受到性能损失。答案是,出于所有意图和目的,没有。关于异常和RTTI有一些棘手的问题,但这些主要是尺寸变化,而不是速度变化。你很难找到一个实际上会受到性能影响的例子,因此编写专用模块似乎不值得。

关于您使用哪些功能的内容很重要。在C ++中很容易弄清楚复制语义,并且会因复制内存而承受巨大的开销。根据我的经验,这是最大的成本 - 在C中你也可以承受这笔费用,但并不像我说的那么容易。

虚函数调用比普通函数稍贵一些。同时强制内联函数比正常函数调用便宜。在这两种情况下,从堆栈推送/弹出参数的成本可能更高。担心函数调用开销虽然在优化过程中应该很晚 - 因为它很少是一个重大问题。

例外情况在投掷时很高(至少在海湾合作委员会中)。但是设置catch语句和使用RAII并没有与之相关的显着成本。这是在GCC编译器(和其他人)中设计的,因此真正只有特殊情况才是昂贵的。

但总结一下:一个优秀的C ++程序员 能够简单地通过在C中编写代码来使代码运行得更快。

答案 1 :(得分:10)

在考虑优化之前

衡量 衡量,在应用优化之前衡量,在应用优化之后衡量,<强>测量<!/强>

如果你必须更快地运行你的代码1纳秒(因为它将被1000人使用,在接下来的1000天内使用1000次而 秒非常重要什么都行。

是的!值得......

  • 更改语言(C ++到C; Python到COBOL; Mathlab到Fortran; PHP到Lisp)
  • 调整编译器(启用/禁用所有-f选项)
  • 使用不同的库(甚至自己编写)

你不能忘记的是衡量!

答案 2 :(得分:1)

pmg钉它。只是衡量而不是全球假设。也可以这样想,像gcc这样的编译器将前端,中端和后端分开。所以前端fortran,c,c ++,ada等最终会使用相同的内部中间语言,如果你能获得大部分优化的话。然后,该通用中间语言将转换为特定目标的汇编程序,并且会发生目标特定的优化。因此,当语言差异很大时,语言可能会也可能不会从前到中引入更多代码,但对于C / C ++,我认为它是相同或非常相似的。现在二进制大小是另一个故事,即使只有C语法,C语言可能会被/或将会变化,这些库可能只被C语言吸收到二进制文件中。不一定会影响执行性能,但如果程序加载到ram中,则可以增加程序文件的成本,从而节省存储和传输差异以及内存要求。在这里再次,只是衡量。

我还添加了度量注释编译到汇编程序和/或反汇编输出并比较不同语言/编译器选择的结果。这可以/将补充您在测量时看到的时间差异。

答案 3 :(得分:1)

这个问题已经被解决了,所以我不会补充这一点。

仅作为一般性问题,假设您已经测量过,并且您已经确定某个C ++(或其他)代码段没有以最佳速度运行(这通常意味着您没有使用正确的工具来完成工作);并且你知道你可以通过用C编写来获得更好的性能,然后肯定,这是值得的。

有一种常见的心态,试图从一个工具(Java或SQL或C ++)做所有事情。不仅仅是马斯洛的锤子,而是他们可以用Java等编写C构造的实际信念。这会导致各种性能问题。架构作为一种真正的职业,是将代码段放置在适当的架构位置或平台中。它是Java,SQL和C的正确组合,可以提供性能。这产生了一个不需要重新访问的应用程序;平安无事的执行。在这种情况下,C ++是否或何时实现此构造函数或无关紧要。

答案 4 :(得分:0)

  

我想知道现代编译器及其优化是否仍然值得用C而不是C ++编写一些关键代码以使其更快。

没有。保持可读性。如果你的团队更喜欢c ++或c,那就更喜欢 - 特别是如果它已经在生产代码中运行了(不要在没有很好理由的情况下重写它)。

  

我知道C ++可能导致在复制类的情况下性能不佳,而它们可以通过引用传递

然后禁止复制和分配

  

或者编译器自动创建类时,通常使用重载运算符和许多其他类似情况

你可以详细说明吗?如果您指的是模板,它们在运行时没有额外的成本(尽管它们可能导致额外的导出符号,从而产生更大的二进制代码)。事实上,如果(例如)转换是必要的,使用模板方法可以提高性能。

  

但对于一个知道如何避免这一切的优秀C ++开发人员来说,是否仍然值得用C编写代码来提高性能?

根据我的经验,专业的c ++开发人员可以创建一个更快,更易维护的程序。

您必须对您使用的语言功能(并且不使用)有所选择。如果你将c ++特性分解为c中可用的集合(例如,删除异常,虚函数调用,rtti),那么你就有了一个良好的开端。如果你学会使用模板,元编程,优化技术,避免类型别名(在c中变得越来越困难或冗长)等等,那么你应该比c更平和或更快 - 一个更容易维护的程序(因为你熟悉c ++)。

如果您习惯使用c ++的功能,请使用c ++。它有很多功能(其中许多功能都考虑了速度/成本),并且可以写成与c(或更快)一样快。

使用模板和元编程,可以将许多运行时变量转换为编译时常量,以获得出色的增益。有时进入微优化领域。