【问题标题】:Is there a great deal of extra overhead when using C++ over C? [closed]在 C 上使用 C++ 时是否有大量额外开销? [关闭]
【发布时间】:2014-05-15 04:44:23
【问题描述】:

我已经使用 C 对微控制器进行了一些编程,但我喜欢 C++ 以其面向对象的特性带来的直觉。

一般来说,使用 C++ 的主要缺点是什么?除了调用关联的构造函数和析构函数的类实例化和删除之外,与使用 C 的等效实现相比,是否存在大量开销?

具体来说,我比较关心以下几个方面:

  • 额外的内存使用 (RAM)
  • 需要额外的指令(以及相应的 CPU 时间)
  • 存储 C++ 程序(即编译结果)所需的额外内存

【问题讨论】:

  • C++ 遵循“你只需为你使用的东西付费”的原则。有一些昂贵的功能,但如果你不使用它们,你就不会为它们受苦。再加上这些都是你无论如何都不能在 C 中做的事情。请注意,强类型特性可以使 C++ 比 C 更快,因为它为编译器提供了更多信息来优化。比较 C 的 qsortstd::sort
  • @Brian:我正要发布那个。这是我的答案的链接:stackoverflow.com/questions/10775087/…
  • @Adam:经典的qsortstd::sort 是一个谬论。没有根本原因qsort 不能同样优化,事实上,如果在stdlib.h 中有内联实现,任何体面的编译器都将如此。当然,您为这种嵌入式微控制器可能非常不受欢迎的内联(以及std::sort)付出了极大的代价。
  • 我通常的回答是你必须测量它。这里的所有答案都为您提供一般性建议,但如果您真的关心性能,则必须进行基准测试。不是任何人工测试,而是您想到的用例。第二个维度是 C++ 的好处。与购买更多内存、可能有更少的错误或更早的版本相比,开发成本是多少?

标签: c++ c microcontroller


【解决方案1】:

用 C++ 编程不会天生就给你一个更慢/更大/程序。然而,这就是在微控制器上更喜欢 C 而不是 C++ 的一些原因:

  • 编写 C++ 编译器比编写 C 编译器要困难得多。因此,不可能为小型处理器找到 C++ 编译器,但总能找到 C 编译器。这可能会或可能不会打扰您。即使它现在不打扰你,如果你想移植你的代码,它可能会在将来。
  • C++ 可以在你背后做事。向量比数组更容易处理,因为很多工作都是为您完成的。但这意味着库正在为您分配内存,并且它会在 想要的时候分配内存。如果内存非常宝贵,那么您可能想要完全控制。此外,如果您的用例中有实时元素,那么您可能希望预先分配所有内存,以便每次调用都是可预测的(如果您达到需要的边界,则插入向量可能需要很长时间增长......这可能意味着将向量复制到堆上的新位置)。
  • C++ 具有占用更多内存的特性,非常易于使用。如果您将函数设为虚拟,那么编译器可能需要有一个虚拟函数表(更多内存,以及稍慢的函数调用)。这可能是您想要的,但这些东西在 C++ 中比在 C 中更容易引入。

总体而言,C++ 将允许您引入比 C 更大、更慢的代码。但是,如果您想要这些功能,那么在 C 中执行它是一件痛苦的事情(想想函数指针而不是虚函数调用......它们实际上是同一件事)。而且 C 版本最终会占用相同的时间和资源,因此使用 C 并没有节省。

【讨论】:

  • 第 1 点是一个很好的观点。关于#2 和#3,我不认为这些是特定于语言选择的。对于#2,这是对动态数组数据结构的批评,而不是对它实现的语言 n 的批评; C++ 也有一个不那么流行的 std::list 用于链表(自定义分配器也可以让您在先前分配的内存中进行分配)。对于 #3,无论语言如何,一个好的代码审查和风格指南政策都会很好,并且可以缓解这种情况。
  • 我真的只是想使用 C++ 来封装某些操作。即,我已经编写了各自的 C 库的 I2C 和 LCD 接口。我只是在看拥有一个 Lcd 类而不是调用许多相关的独立函数是多么直观。当然,这实际上几乎是一回事,但 Atmel Studio 支持 C++,因此具有适当的代码完整功能,这将使这变得非常简单。
  • 使用向量,您可以预先分配数组,从而有效地控制执行的分配量。如果您真的想要完全动态大小的数组,std::vector 通常是用 C 编写的自制版本的更有效的解决方案。
  • @sherrellbc,作为试运行,您可能希望严格维护 C 接口(C++ 中的外部“C”),但提供 C++ 中的实现。这将允许您在特定 C API 的实现中测试 C++,以全面检查其在项目中的使用情况,同时限制风险,以防您毕竟需要在 C 中重新实现该组件。
  • @sherrellbc 如果您的意思是在 C++ 类中包装 C 接口,我会说这不值得。如果 C++ 包装器允许您抽象一些东西,那么也许可以。例如,如果几个 LCD 相似,而您为所有 LCD 创建了一个通用接口。使用好的编译器(参见 dave 的第 1 点),可以完全优化瘦包装器。
【解决方案2】:

动态调度(即标记为virtual 的方法)比非虚拟方法的成本略高(尽管可以忽略不计)(但是,好消息,您不必将方法标记为virtual,除非您打算这样做覆盖它,当你使用它时,它可能会比你在 C 中手工制作的任何东西都要快)并且异常处理可能很慢(尽管你不需要在代码中使用异常)。除此之外,没有什么区别,只是 C++ 比等效的 C 代码大大简化了代码。

【讨论】:

  • 编写 C 的重点不是编写与您在 C++ 中编写的等效的内容,而是编写在 C++ 中高度非惯用但在大小和性能方面非常优越的东西。一个典型的例子是在你的结构中直接使用 prev/next 指针,并使用一个简单的 for 循环而不是使用列表容器对象来遍历它们。
  • @R,除了提供与其他语言的绑定之外,我还没有看到一个令人信服的用例选择 C ​​而不是 C++。现代编译器优化使 C++ 具有同样的性能,而该语言——如果使用得当的话——比 C 更具可读性。
猜你喜欢
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 2022-01-11
  • 2020-10-09
相关资源
最近更新 更多