这是一个面试问题,面试已经做完了。
什么东西会让C++比C慢?
面试官问得很深,总是问“还有别的吗?”每当我说什么的时候。
我的想法是:
C语言中没有的C++特性可能会有一些代价。
例如,如果我们使用赋值在构造函数中初始化类的成员,而不是通过初始化列表,那么成员的默认构造函数可能会在构造函数的主体之前被调用一次,然后该值就会被赋值擦除。
需要通过查找虚函数指针来调用虚函数。这是一个开销。
有更好的主意吗?
任何帮助都将不胜感激。
谢谢!
发布于 2012-05-27 23:27:53
没什么。事实上,C++比C更快。你有没有把std::sort比作qsort?
人们说虚拟函数调用起来很费时。确实如此。但是在vtable中查找的C等价物也是如此。如果用两种语言编写等价的逻辑,则C++版本将更易维护、更干净、更快。
编辑:哦,是的,如果你愿意,你可以从C++调用printf,或者如果你愿意的话,可以完全重做流实现。
我有没有提到过,由于错误的空终止符而崩溃的程序的性能是相当无关紧要的?
宏和内联函数将像C++中的模板一样“膨胀”C可执行文件。
发布于 2012-05-28 02:26:47
与C相比,C++本身并没有什么慢的地方,但是惯用的C++代码往往比惯用的C代码执行相同的任务要慢得多,也更重。在这里,惯用这个词是关键;如果您编写C代码来执行任务,与在C++中执行该任务的方式完全相同,那么执行速度也会很慢。另一方面,如果您意识到C++中的隐藏成本通常会悄悄增加,那么您可以努力将它们保持在最低水平,并在不花费太多成本的情况下获得C++的好处。
首先也是最重要的是动态内存分配。在C语言中,您可以看到动态内存分配的每一点内容,因为它们都是显式的(要么以调用malloc的形式,要么以调用返回已分配对象的第三方库函数的形式)。在C++中,许多对象的存储持续时间是自动的类对象仍然会产生动态内存分配,因为它们的构造函数中发生了隐藏的分配。一个好的C++ STL (或第三方库)实现可以通过在对象本身中包含小缓冲区以及仅在需要大缓冲区时执行动态分配来避免大量此类成本,但实际上很少有人这样做。(如果我没记错的话,应该是llvm的libc++支持,但GCC的libstdc++不支持。)由于这是一个实现质量问题,通常不在您自己的代码的控制范围内,因此您可以在这里做的主要事情是了解自动对象分配动态内存的可能性,并避免创建超过您需要的内存(例如,在可能的情况下使用指针或引用)。这对您的代码也有其他好处。
另一个重要的领域是字符串处理。在惯用的C语言中,字符串是用snprintf或类似的语言一举构建的。在C++和许多其他具有更强大的字符串类/类型的语言中,字符串的连接(逐段构造)是惯用的。这是非常低效的,导致多个分配/释放步骤、副本等,更不用说由此产生的内存碎片。我不确定C++的最佳实践会涉及到什么(我不太精通C++),但应该有办法将这种影响降到最低。
当然,最常见的是隐藏代码。这是一种包罗万象的方法。在C++中编写代码很容易,因此会执行许多您从未见过的额外代码。构造函数/析构函数、重载操作符和模板是最明显的原因。同样,如果你想用C语言做同样的事情,成本也是一样的,但不同的是,在C语言中,你马上就能看到成本,因为你必须自己写。
发布于 2012-05-28 05:04:21
哇..。答案中有很多对C++的爱,所以我会以魔鬼代言人的身份大喊大叫。
在原子语言范围内,我同意在C++中很少或根本没有明显“慢”的执行。在更高的层次上,它变得很复杂。C++是一个有用的工具,但它通常是一个不适当的panache,作为所有问题的解决方案。当我们使用最简单的语言来描述问题时,效果会更好,有时是C++,有时则是……汇编,操作码,解释语言。
C++在很大程度上依赖于编译器来“解释”意图,通过多次迭代遍历模板、类、宏等的许多层。遍历转换的每个循环都有可能遇到law of unintended consequences。据我所知,处理器没有本机处理C++构造的寄存器或操作码,所以每个构造都必须被分解成一个简化的部分。在这一领域,编译器和代码标准是王道。在某些情况下,它在哲学上相当于一个拥有数学博士学位的教师(编译器)教三年级学生(处理器)。
我喜欢C++并保守地使用它,但这些年来我很少看到它写得很好。我想强迫一些人查看最终由构建返回的程序集或机器代码,直到他们了解它有多复杂。糟糕的C语言是一回事,糟糕的C++可能会变得更糟。
面试的更好答案是...“您的团队什么时候会认为C++不是问题的答案?”
https://stackoverflow.com/questions/10775087
复制相似问题