什么事情(或在什么情况下)可以使C++比 C 慢

What things (or in what cases) can make C++ slower than C ?

本文关键字:C++ 可以使 情况下 在什么 什么      更新时间:2023-10-16

这是一个面试问题,面试已经完成。

什么东西可以使C++比C慢?

面试官问得很深,每当我说什么时,总是问"还有什么事吗?

我的想法:

C++ C 中不可用的功能可能会产生一些成本。

例如,如果我们使用 assignment 来初始化构造函数中的类成员,而不是通过初始化列表,则成员的默认构造函数可以在构造函数的主体之前调用一次,然后该值被赋值清除。

虚拟函数需要通过搜索虚函数指针来调用。这是一个开销。

有什么更好的主意吗?

任何帮助将不胜感激。

谢谢!!!

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 中,您可以立即看到成本,因为您必须自己编写。

什么都没有。事实上,C++比C.Ever std::sortqsort更快?

人们说虚拟功能需要时间来调用。他们确实如此。但 C 也相当于在 vtable 中查找。如果用两种语言编写等效逻辑,则C++版本将更易于维护、更干净、更快速。

编辑:哦,是的,如果需要,您可以从C++调用printf,或者如果需要,可以完全重新执行流实现。

我有没有提到由于放错位置的 NULL 终止符而崩溃的程序的性能是相当无关紧要的?

宏和内联函数会像模板一样"膨胀"C 可执行文件C++。

哇...答案中有很多对C++的爱,所以我会作为魔鬼代言人咆哮一下。

在原子语言尺度上,我同意很少或没有什么本质上显着的"慢"执行C++。在更高级别,它变得很复杂。C++是一个有用的工具,但通常是一种不恰当的华丽,作为所有问题的解决方案。当我们使用最简单的语言来描述问题时会更好,有时C++其他时候......汇编、操作码、解释型语言。

C++在更大程度上依赖于编译器来"解释"意图,通过多次迭代爬取模板、类、宏等的许多层。翻译中的每个循环都有可能遇到意外后果定律。据我所知,处理器没有寄存器或操作码来原生处理C++拥有的结构,因此每个都必须分解为简化的部分。在这个领域,编译器和代码标准是王道。在某些情况下,它在哲学上相当于数学博士的老师(编译器)教三年级学生(处理器)。

我喜欢C++并保守地使用它,但多年来我很少看到它写得好。我想强迫一些人查看最终由构建反刍的汇编或机器代码,直到他们了解它有多复杂。坏C是一回事,坏C++可以成倍地恶化。

面试的更好答案..."你的团队什么时候会认为C++不是问题的答案?"

C++中的大多数功能都是解决 C 语言中(潜在)问题的解决方案(例如:确保所创建数据包有效性的构造函数(C 中的 struct

这意味着要用 C 编写一个正确的程序来尝试避免存在C++功能的问题,您必须执行与 C++ 在幕后执行的类似操作。 这导致在两种情况下具有相似的性能。

当然,您始终可以编写"更快"的草率程序,但并非在所有情况下都能正常工作

有什么更好的主意吗? 任何帮助将不胜感激。

C++中的 STL 很少比 C 中特殊编码的等效物慢。 但是,STL 的便利性偶尔会导致编写较慢的代码。 例如,假设一组固定的 100 个项目,从中选择 10 或 15 个变量。 假设程序的时间关键循环多次询问是否已选择项i。 支持这种时间关键循环的快速数据结构将是 100 个布尔值的数组(或向量等)。 但是,填充std::set<size_t>可能比填充数组更容易在C++中编码。 出于这个原因,C++程序员可能更喜欢集合而不是数组。

当然,较慢的代码是否是一个问题取决于时间关键型循环将看到多少服务。 如果对数组技术进行编程需要额外的半小时,并且在程序生命周期内节省的总执行时间为 0.5 秒,则设置技术可能更可取。 另一方面,如果总执行时间节省为 30 天,则数组技术可能更可取。

沿着这些思路,可能会给出许多类似的答案。 祝你面试顺利。

C 有 restrict ,C++没有,尽管大多数编译器都有它作为扩展。

还有C++没有的可变长度数组。

先验不是性能问题,但LLVM代码库既不使用RTTI也不使用异常,因为它们被认为在代码大小方面成本太高。