函数实际上比函数指针快吗?

根据斯科特·迈耶斯(Scott Meyers)的观点,C ++超越C的一个方面是函数对象比函数指针要快。 他说这是因为内联了功能对象,从而提高了速度。

我对此有两个问题:

  1. 我们如何验证实际上是内联的函数对象? 我们可以在实践中验证吗?

  2. 函数对象的内联是否取决于我们使用的编译器,还是所有编译器的行为都如此?

3个解决方案
76 votes

C ++和C标准为编译器留出了很多自由。 编译器可以自由地在每条指令之间计数到10亿,或者只有在整数中有质数时才这样做。

体面的“真实”编译器不会这样做。 这是实施质量的问题。

每个真正的编译器都会将函数对象内联到诸如std::sort之类的东西中。 在这些情况下,检测需要内联的内容非常容易,因为类型信息附带了需要内联的代码。

使用函数指针很难做到这一点。 使用将所有内容都转换为std::sortqsort指针的函数指针执行此操作更加困难。

这样的效果是,实际上,对std::sort的C风格调用与对qsort的C ++风格调用可以为qsort带来很大的优势。

此处显示的std::sortqsort慢大约qsort的2倍,这是对随机排列的整数进行排序的荒谬简单情况。

检查实际的汇编代码输出主要是一个细节,并且需要大量工作才能获得很少的回报。 以具体的实际示例为例,您可以了解影响的真正程度。

clang,gcc和MSVC的全部3个都能够使std::sort大大快于其qsort。由于这是一个简单的优化,而将函数指针优化为内联调用却并非如此,因此您希望使用较少的主要编译器不会比 qsort

Yakk - Adam Nevraumont answered 2019-10-09T17:46:52Z
18 votes
  1. 我们如何验证函数对象实际上是内联的? 我们可以在实践中验证吗?

当然,请检查最终发出的汇编代码。

  1. 内联函数对象取决于我们使用的编译器,还是所有编译器的行为都一样?

它在很大程度上取决于编译器的实现和所使用的优化级别。
所以不,不能保证特定的编译器(链接器)会如此运行。

但是,不能内联通过函数指针进行的调用。


据他介绍,函数对象是内联的,因此速度有所提高。

IMO“内联功能对象”应该更好地阅读(或听到,我不知道该引用来自何处):

可以内联函数对象,而不能通过函数指针进行调用。

πάντα ῥεῖ answered 2019-10-09T17:48:09Z
1 votes

是的,函数对象可能会导致更快的代码。 但是确保这一点的唯一方法是进行基准测试。

  1. 该文档说:“由于多种原因,GCC仍可能无法内联函数;可以使用inline选项确定是否未内联函数以及为什么不内联。”

  2. 当然,这将取决于编译器,版本,标志等。有时内联会适得其反(代码膨胀等),因此每个编译器都有自己的一套规则来决定是否应内联函数。 顺便说一句,inline关键字只是一个提示,某些库(例如eigen)很难执行内联。

YvesgereY answered 2019-10-09T17:48:47Z
translate from https://stackoverflow.com:/questions/40809985/are-functors-actually-faster-than-pointers-to-functions