在C ++代码中使用纯C库是否会导致性能下降/损失?

在C ++代码中使用纯C库是否会导致性能下降/损失?

问题描述:

我看到了此链接,但我并没有要求使用 extern的代码会降低性能。我的意思是没有 extern,在C ++中使用C库时是否存在上下文切换?
在C ++应用程序中使用纯C(非类包装)函数时是否有问题?

I saw this link but I'm not asking for a performance degradation for code using "extern". I mean without "extern", is there "context switching" when using C library in C++? Are there any problems when using pure C (not class-wrapped) functions in C++ application?

C和C ++都是编程语言规范(用英语编写,请参见例如 n1570 (针对C11的规范),而不是谈论性能(而是关于程序的行为,即关于语义)。

Both C and C++ are programming language specifications (written in English, see e.g. n1570 for the specification of C11) and do not speak about performance (but about behavior of the program, i.e. about semantics).

但是,您可能会使用 GCC Clang 不会带来任何性能损失,因为它建立了相同类型的中间内部表示形式(例如GIMPLE for GCC,和LLVM for Clang),并且因为C和C ++代码使用兼容的 ABI s和呼叫约定

However, you are likely to use a compiler such as GCC or Clang which don't bring any performance penalty, because it builds the same kind of intermediate internal representation (e.g. GIMPLE for GCC, and LLVM for Clang) for both C and C++ languages, and because C and C++ code use compatible ABIs and calling conventions.

在练习外部 C 不会更改任何调用约定,而是禁用名称修改。但是,它对编译器的确切影响特定于该编译器。它可能会(或不会)禁用内联(但请考虑 -flto 用于GCC中的链接时间优化。

In practice extern "C" don't change any calling convention but disables name mangling. However, its exact influence on the compiler is specific to that compiler. It might (or not) disable inlining (but consider -flto for link-time-optimization in GCC).

某些C编译器(例如 tinycc )产生的代码性能不佳。甚至 GCC Clang ,当与 -O0 一起使用或没有明确一起使用时,启用优化(例如,通过传递 -O1 -O2 等)可能会产生缓慢的代码(并且通过

Some C compilers (e.g. tinycc) produce code with poor performance. Even GCC or Clang, when used with -O0 or without explicitly enabling optimization (e.g. by passing -O1 or -O2 etc...) might produce slow code (and optimizations are by default disabled with it).

顺便说一句,C ++旨在与C互操作(并且这种强大的约束解释了C ++的大多数缺陷)。

BTW, C++ was designed to be interoperable with C (and that strong constraint explains most of the deficiencies of C++).

在某些情况下,真正的C ++代码可能比相应的真正C代码稍微快。例如,要对数字数组进行排序,您将使用 std :: array std :: sort 以及纯C ++中的比较操作可能会内联。使用C代码,您只需使用 qsort ,每个比较都会通过间接方式进行函数调用(因为编译器没有内联 qsort ,即使理论上也可以...)。

In some cases, genuine C++ code might be slightly faster than corresponding genuine C code. For example, to sort an array of numbers, you'll use std::array and std::sort in genuine C++, and the compare operations in the sort are likely to get inlined. With C code, you'll just use qsort and each compare goes through an indirect function call (because the compiler is not inlining qsort, even if in theory it could...).

在其他情况下,真正的C ++代码可能会稍微慢一些。例如, :: operator new 的几个(但不是全部)实现只是调用 malloc (然后检查失败)

In some other cases, genuine C++ code might be slightly slower; for example, several (but not all) implementations of ::operator new are simply calling malloc (then checking against failure) but are not inlined.

实际上,由于调用约定是兼容的,因此从C ++代码调用C代码或从C代码调用C ++代码不会受到任何惩罚。

In practice, there is no penalty in calling C code from C++ code, or C++ code from C code, since the calling conventions are compatible.

C longjmp 设施可能比抛出C ++异常要快,但是它们没有相同的语义(请参见堆栈展开)和 longjmp 在整个C ++代码中混合得不好。

The C longjmp facility is probably faster than throwing C++ exceptions, but they don't have the same semantics (see stack unwinding) and longjmp doesn't mix well accross C++ code.

关于性能,编写(使用正版C和正版C ++)两倍的代码和基准。您可能会发现C和C ++之间有很小的变化(最多只有几个百分点),因此我一点也不会打扰(并且您对性能的担忧实际上是不合理的)。

If you care that much about performance, write (in genuine C and in genuine C++) twice your code and benchmark. You are likely to observe a small change (a few percents at most) between C and C++, so I would not bother at all (and your performance concerns are practically unjustified).

上下文切换是与操作系统多任务,并发生在流程上机器代码可执行文件.org / wiki / Preemption_(计算) rel = noreferrer>抢占。 可执行文件的获取方式(从C编译器,C ++编译器,Go编译器,完全不相关(因为可以在任何 machine 指令中在中断)。阅读诸如> 操作系统:三件容易的东西 之类的书。 。

Context switch is a concept related to operating system and multitasking and happens on processes running machine code executable during preemption. How that executable is obtained (from a C compiler, from a C++ compiler, from a Go compiler, from an SBCL compiler, or being an interpreter of some other language like Perl or bytecode Python) is totally irrelevant (since a context switch can happen at any machine instruction, during interrupts). Read some books like Operating Systems: Three Eeasy Pieces.