c++ - 模板元编程是否比等效的 C 代码更快?

标签 c++ c language-agnostic templates metaprogramming

模板元编程是否比等效的 C 代码更快? (我说的是运行时性能):)

最佳答案

首先,免责声明:
我认为您要问的不仅仅是模板元编程,还有泛型编程。这两个概念密切相关,并且对于每个概念所包含的内容没有确切的定义。但简而言之,模板元编程本质上是使用模板编写程序,并在编译时对其进行评估。 (这使得它在运行时完全免费。什么也没发生。值(或更常见的是,类型)已经由编译器计算出来,并且可以作为常量(const 变量或枚举)或作为 typedef 使用嵌套在一个类中(如果你用它来“计算”一个类型)。

通用编程正在使用模板,并在必要时使用模板元编程,以创建具有所有类型和任何类型的相同(并且没有性能损失)的通用代码。我将在下面使用两者的示例。

模板元编程的一个常见用途是使类型能够在泛型编程中使用,即使它们不是为泛型编程而设计的。

由于模板元编程在技术上完全发生在编译时,您的问题与泛型编程更相关,泛型编程仍然发生在运行时,但效率很高,因为它可以专门用于在编译时使用的精确类型。

总之……

取决于您如何定义“等效的 C 代码”。

模板元编程(或一般的泛型编程)的诀窍在于它允许将大量计算转移到编译时,并且它支持灵活的、参数化的代码,与硬编码值一样高效。

显示的代码 here例如在编译时计算斐波那契数列中的一个数字。

C++ 代码 ' unsigned long fib11 = fibonacci<11uL>::value ',依赖于该链接中定义的模板元程序,并且与 C 代码一样高效 ' unsigned long fib11 = 89uL '。模板在编译时进行评估,产生一个可以分配给变量的常量。所以在运行时,代码实际上与简单的赋值相同。

因此,如果那是“等效的 C 代码”,则性能是相同的。
如果等效的 C 代码是“一个可以计算任意斐波那契数的程序,用于查找序列中的第 11 个数字”,那么 C 版本会慢得多,因为它必须作为一个函数来实现,它计算值在运行时。但这是“等效的 C 代码”,因为它是一个具有相同灵活性的 C 程序(它不仅仅是一个硬编码的常量,而是一个可以返回斐波那契数列中的任何数字的实际函数)。

当然,这通常不是很有用。但它几乎是模板元编程的典型例子。

泛型编程的一个更现实的例子是排序。

在 C 中,你有 qsort标准库函数采用数组和比较器函数指针。对这个函数指针的调用不能被内联(除了在微不足道的情况下),因为在编译时,不知道将调用哪个函数。

当然,另一种选择是为您的特定数据类型设计的手写排序函数。

在 C++ 中,等效的是函数模板 std::sort .它也需要一个比较器,但它不是一个函数指针,而是一个函数对象,如下所示:

struct MyComp {
  bool operator()(const MyType& lhs, const MyType& rhs) {
     // return true if lhs < rhs, however this operation is defined for MyType objects
  }
};

这可以被内联。 std::sort function 传递了一个模板参数,因此它知道比较器的确切类型,因此它知道比较器函数不仅仅是一个未知的函数指针,而是 MyComp::operator() .

最终结果是 C++ 函数 std::sort与您在相同排序算法的 C 中手动编码的实现完全一样有效。

再说一次,如果那是“等效的 C 代码”,那么性能是相同的。
但是,如果“等效的 C 代码”是“可以应用于任何类型的通用排序函数,并允许用户定义的比较器”,那么 C++ 中的通用编程版本的效率要高得多。

这真的是诀窍。泛型编程和模板元编程并不“比 C 快”。它们是实现与手工编码和硬编码 C 一样快的通用、可重用代码的方法

这是一种两全其美的方式。硬编码算法的性能,以及通用参数化算法的灵活性和可重用性。

关于c++ - 模板元编程是否比等效的 C 代码更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1182672/

相关文章:

c++ - 检查两个矩形是否重叠或边缘接触

c++ - gdb - 从核心文件中得到完全意外的错误

c - 包括 malloc_np.h 的便携方式

language-agnostic - 可搜索的堆结构

web-services - 消费服务消费其他服务

C++11 数组初始化不会调用复制构造函数

c++ - ZeroMQ 链接器错误 C++

c - 如何在 C 中正确实现健壮的堆栈

c - 运行此代码时显示段错误错误

algorithm - 超集搜索