C++的编译和执行时间与C源代码比较
我不确定这是否是有效的比较或有效的陈述,但多年来我听到人们声称用 C++ 编写的程序通常比用 C 编写的程序需要更长的时间,并且用 C++ 编写的应用程序是运行时通常比用 C 编写的慢。
这些说法是否属实?
除了获得 C++ 提供的 OOP 灵活性的好处之外,是否应该纯粹从编译/执行时间的角度考虑上述比较?
我希望这不会因为太笼统或模糊而结束,这只是试图了解多年来我从许多程序员(主要是 C 程序员)那里听到的陈述的实际事实。
I am not sure if this is a valid comparison or a valid statement but over the years I have heard folks claiming that the programs written in C++ generally take a longer time for compilation than the same written in C and that the applications coded in C++ are generally slower at run time than ones written in C.
Is there any truth in these statements?
Apart from reaping the benefits of OOP flexibility that C++ provides, should the above comparison be given a consideration purely from a compilation/execution time perspective?
I hope that this doesn't get closed as too generic or vague, it is just an attempt to know the actual facts about statements I have been hearing over the years from many programmers(C programmers predominantly).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我将回答这个问题的一个非常客观的特定部分。使用模板的 C++ 代码的编译速度比 C 代码慢。如果您不使用模板(如果您使用标准库,则可能会使用模板),那么编译时间应该非常相似。
编辑:
就运行时间而言,它更加主观。尽管 C 可能是一种较低级别的语言,但 C++ 优化器变得非常好,并且 C++ 有助于更自然地表示现实世界的概念。如果用代码更容易表示您的需求(正如我在 C++ 中所主张的那样),那么通常比用其他语言更容易编写更好(且性能更高)的代码。我认为没有任何客观数据表明 C 或 C++ 在所有可能的情况下都更快。我实际上建议根据项目需求选择您的语言,然后用该语言编写。如果速度太慢,请分析并继续使用正常的性能改进技术。
I'll answer one specific part of the question that's pretty objective. C++ code that uses templates is going to be slower to compile than C code. If you don't use templates (which you probably will if you use the standard library) it should be very similar compilation time.
EDIT:
In terms of runtime it's much more subjective. Even though C may be a somewhat lower level language, C++ optimizers are getting really good, and C++ lends itself to more naturally representing real world concepts. If it's easier to represent your requirements in code (as I'd argue in C++) it's often easier to write better (and more performant) code than you would in another language. I don't think there's any objective data showing C or C++ being faster in all possible cases. I would actually suggest picking your language based on project needs and then write it in that language. If things are too slow, profile and proceed with normal performance improvement techniques.
相对运行速度有点难以预测。曾经,当大多数人认为 C++ 就是继承,并且大量使用虚函数(即使它们不是特别合适时)时,用 C++ 编写的代码通常会慢一些对于
(我们大多数人认为的)现代 C++,情况往往是相反的:模板提供了足够多的编译时灵活性,您可以经常生成比 C 中任何合理的等效项明显更快的代码。总是可以通过编写相当于“扩展”模板结果的专门代码来避免这种情况——但实际上,这样做非常罕见,而且相当昂贵。
C++ 也有一种写得更通用的趋势——例如,将数据读入
std::string
或std::vector
(或者std::vector
),因此用户可以输入任意数量的数据,而不会发生缓冲区溢出或数据在某个时刻被截断。在 C 语言中,更常见的是有人只编写固定大小的缓冲区,如果您输入的内容超过这个值,它就会溢出或截断。显然,你需要为此付出一些代价——C++ 代码通常最终会使用动态分配 (new
),这通常比仅定义数组要慢。 OTOH,如果您编写 C 来完成同样的事情,您最终会编写大量额外的代码,并且它的运行速度通常与 C++ 版本大致相同。换句话说,编写 C 语言非常容易,它对于基准测试和一次性实用程序等方面的速度明显更快,但速度优势在必须强大的实际代码中消失了。在后一种情况下,您通常可以期望的最好结果是 C 代码相当于 C++ 版本,而且老实说,即使做得很好也相当不寻常(至少 IME)。
比较编译速度并不容易。一方面,模板确实可能很慢——至少对于大多数编译器来说,实例化模板的成本相当昂贵。在逐行的基础上,毫无疑问,C 几乎总是比任何使用模板的 C++ 更快。问题在于,逐行比较很少有多大意义——10 行 C++ 可能很容易相当于数百甚至数千行 C。只要你只看在编译时(而不是开发时),无论如何,平衡可能有利于 C,但肯定不会几乎像最初看起来的情况那样引人注目。这也很大程度上取决于编译器:举个例子,clang 在这方面比 gcc 做得好很多(而且 gcc 在过去几年也有了很大的改进)。
The relatively runtime speed is a bit hard to predict. At one time, when most people thought of C++ as being all about inheritance, and used virtual functions a lot (even when they weren't particularly appropriate), code written in C++ was typically a little bit slower than equivalent C.
With (what most of us would consider) modern C++, the reverse tends to be true: templates give enough more compile-time flexibility that you can frequently produce code that's noticeably faster than any reasonable equivalent in C. In theory you could always avoid that by writing specialized code equivalent to the result of "expanding" a template -- but in reality, doing so is exceedingly rare, and quite expensive.
There is something of a tendency for C++ to be written somewhat more generally as well -- just for example, reading data into
std::string
orstd::vector
(orstd::vector<std::string>
) so the user can enter an arbitrary amount of data without buffer overflow or the data simply be truncated at some point. In C it's a lot more common to see somebody just code up a fixed-size buffer, and if you enter more than that, it either overflows or truncates. Obviously enough, you pay something for that -- the C++ code typically ends up using dynamic allocation (new
), which is typically slower than just defining an array. OTOH, if you write C to accomplish the same thing, you end up writing a lot of extra code, and it typically runs about the same speed as the C++ version.In other words, it's pretty easy to write C that's noticeably faster for things like benchmarks and single-use utilities, but the speed advantage evaporates in real code that has to be robust. In the latter case, about the best you can usually hope for is that the C code is equivalent to a C++ version, and in all honesty doing even that well is fairly unusual (at least IME).
Comparing compilation speed is no easier. On one hand, it's absolutely true that templates can be slow -- at least with most compilers, instantiating templates is quite expensive. On a line-for-line basis, there's no question that C will almost always be faster than anything in C++ that uses templates much. The problem with that is that a line-for-line comparison rarely makes much sense -- 10 lines of C++ may easily be equivalent to hundreds or even thousands of lines of C. As long as you look only at compile time (not development time), the balance probably favors C anyway, but certainly not by nearly as dramatic a margin as might initially seem to be the case. This also depends heavily on the compiler: just for example, clang does a lot better than gcc in this respect (and gcc has improved a lot in the last few years too).
仅当您使用某些特定于 C++ 的功能时,C++ 与 C 的运行时间才会受到影响。与返回错误代码和直接调用相比,异常和虚函数调用会增加运行时间。另一方面,如果您发现自己在 C 中使用函数指针(例如 GTK 就是这样做的),那么您至少已经为虚拟函数付出了部分代价。在每个函数返回后检查错误代码也会消耗时间 - 当您使用异常时,您不会这样做。
另一方面,C++ 中的内联和模板可能允许您在编译时完成大量工作 - C 推迟到运行时的工作。在某些情况下,C++ 最终可能比 C 更快。
The run time of C++ versus C would suffer only if you use certain C++-specific features. Exceptions and virtual function calls add to run time compared to returning error code and direct calls. On the other hand, if you find yourself using function pointers in C (as, say, GTK does) you are already paying at least some of the price for virtual functions. And checking error code after each function return will consume time too - you don't do it when you use exceptions.
On the other hand, inlining and templates in C++ may allow you to do a lot of work compile-time - work that C defers to run time. In some cases, C++ may end up faster than C.
如果你编译的代码与 C 和 C++ 相同,应该没有区别。
如果您让编译器为您完成这项工作(例如扩展模板),那么这将需要一些时间。如果您在 C 中使用剪切和粘贴或一些复杂的宏来执行相同的操作,则会占用您的时间。
在某些情况下,模板的内联扩展实际上会产生比等效 C 代码更专业且运行更快的代码。就像这里:
http://www2.research.att.com/~bs/new_learning。 pdf
或者此报告显示许多 C++ 功能没有运行时成本:
http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf
If you compile the same code as C and C++, there should be no difference.
If you let the compiler do the job for you, like expanding templates, that will take some time. If you do the same in C, with cut-and-paste or some intricate macros, it will take up your time instead.
In some cases, inline expansion of templates will actually result in code that is more specialized and runs faster than the equivalent C code. Like here:
http://www2.research.att.com/~bs/new_learning.pdf
Or this report showing that many C++ features have no runtime cost:
http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf
虽然这是一个老问题,但我想在这里添加我的 5 美分,因为我可能不是唯一一个通过搜索引擎找到这个问题的人。
我不能评论编译速度,只能评论执行速度:
据我所知,c++ 中只有一项功能会影响性能,即使您不使用它。此功能是 c++ 异常,因为它们会阻止一些编译器优化(这就是 c++11 中引入
noexcept
的原因)。但是,如果您使用某种错误检查机制,那么异常可能比返回值检查和大量if else
语句的组合更有效。如果您必须将错误升级到堆栈,则尤其如此。无论如何,如果你在编译期间关闭异常,c++不会引入任何开销,除非你故意使用相关功能的地方(例如,如果你不使用虚函数,则不必为多态性付出代价),而大多数功能都会引入根本没有运行时开销(重载、模板、命名空间等)。
另一方面,大多数形式的泛型代码在 C++ 中比在 C 中的等效代码快得多,因为 C++ 提供了内置机制(模板和类)来执行此操作。一个典型的例子是 c 的 qsort 与 c++ 的 std::sort。 C++ 版本通常要快得多,因为在排序内部,所使用的比较器函数在编译时是已知的,这至少可以节省通过函数查找的调用,并且在最好的情况下允许许多额外的编译器优化。
话虽如此,C++ 的“问题”在于它很容易向用户隐藏复杂性,使得看似无辜的代码可能比预期慢得多。这主要是由于运算符重载、多态性和构造函数/析构函数造成的,但即使是对成员函数的简单调用也会隐藏传递的 this 指针,该指针也不是 NOP。
考虑运算符重载:当您在 c 中看到
*
时,您知道这是(在大多数体系结构上)一条单一的、廉价的汇编指令,另一方面,在 c++ 中它可能是一个复杂的函数调用(想想关于矩阵乘法)。这并不意味着您可以更快地在 c 中实现相同的功能,但在 c++ 中您不会直接看到这可能是一个昂贵的操作。析构函数也是类似的情况:在“现代”c++ 中,您几乎不会通过删除看到任何显式析构,但任何超出范围的局部变量都可能会触发对(虚拟)析构函数的昂贵调用,而无需一行代码表明这一点(当然忽略
}
)。最后,有些人(尤其是来自 Java 的人)倾向于编写带有大量虚函数的复杂类层次结构,其中对此类函数的每次调用都是隐藏的间接函数调用,这很难或不可能优化。
因此,虽然对程序员隐藏复杂性通常是一件好事,但如果程序员不知道这些“易于使用”构造的成本,它有时会对运行时产生不利影响。
作为总结,我想说,C++ 使缺乏经验的程序员更容易编写缓慢的代码(因为他们无法直接看到程序中的低效率)。但是,C++ 还允许优秀的程序员比 C 更快地编写“好”、正确且快速的代码 - 这让他们有更多的时间在真正需要时考虑优化。
PS:
我没有提到的两件事(可能是我忘记的)是 c++ 进行复杂编译时计算的能力(感谢模板和 constexpr)和 c 的 limit 关键字。这是因为还没有在时间关键的程序中使用它们中的任何一个,所以我无法评论它们的一般用途和现实世界的性能优势。
Although its an old question I'd like to add my 5cents here, as I'm probably not the only one who finds this question via a search engine.
I can't comment on compilation speed but on execution speed:
To the best of my knowledge, there is only one feature in c++ that costs performance, even if you don't use it. This feature are the c++ exceptions, because they prevent a few compiler optimizations (that is the reason, why
noexcept
was introduced in c++11). However, if you use some kind of error checking mechanism, then exceptions are probably more efficient than the combination of return value checking and a lotif else
statements. This is especially true, if you have to escalate an error up the stack.Anyway, if you turn off exceptions during compilation, c++ introduces no overhead, except in places where you deliberately use the associated features (e.g. you dont't have to pay for polymorphism if you don't use virtual functions), whereas most features introduce no runtime overhead at all (overloading, templates, namespaces a.s.o.).
On the other hand, most forms of generic code will be much faster in c++ than the equivalent in c, because c++ provides the built-in mechanisms (templates and classes) to do this. A typical example is c's qsort vs c++'s std::sort. The c++ version is usually much faster, because inside sort, the used comparator function is known at compile time, which at least saves a call through a function lookup and in the best case allows a lot of additional compiler optimizations.
That being said, the "problem" with c++ is that it's easy to hide complexity from the user such that seemingly innocent code might be much slower than expected. This is mainly due to operator overloading, polymorphism and constructors/destructors, but even a simple call to a member function hides the passed
this
-pointer which also isn't a NOP.Considering operator overloading: When you see a
*
in c, you know this is (on most architectures) a single, cheap assembler instruction, in c++ on the other hand it can be a complex function call (think about matrix multiplication). That doesn't mean, you could implement the same functionality in c any faster but in c++ you don't directly see that this might be an expensive operation.Destructors are a similar case: In "modern" c++, you will hardly see any explicit destructions via delete but any local variable that goes out of scope might potentially trigger an expensive call to a (virtual) destructor without a single line of code indicating this (ignoring
}
of course).And finally, some people (especially coming from Java) tend to write complex class hierarchies with lots of virtual functions, where each call to such a function is a hidden indirect function call which is difficult or impossible to optimize.
So while hiding complexity from the programmer is in general a good thing it sometimes has an adverse effect on runtime, if the programmer is not aware of the costs of these "easy to use" constructs.
As a summary I would say, that c++ makes it easier for inexperienced programmers to write slow code (because they don't directly see inefficiencies in a program). But c++ also allows good programmers to write "good", correct and fast code faster than with c - which gives them more time to think about optimizations when they really are necessary.
P.S.:
Two things I haven't mentioned (probably among others that I simply forgot) are c++'s ability for complex compile time computations (thanks to templates and constexpr) and c's restrict keyword. This is because didn't use either of them in time critical programs yet and so I can't comment on their general usefulness and the real world performance benefit.
C 应用程序的编译和执行速度比 C++ 应用程序更快。
C++ 应用程序在运行时通常较慢,并且编译速度比 C 程序慢得多。
查看这些链接:
C applications are faster to compile and execute than C++ applications.
C++ applications are generally slower at runtime, and are much slower to compile than C programs.
Look at these links: