61

根据 Scott Meyers 的说法,C++ 优于 C 的一个方面是函数对象比函数指针更快。他说这是因为函数对象是内联的,这提高了速度。

我对此有两个问题:

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

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

4

3 回答 3

77

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

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

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

使用函数指针这样做更难。使用所有内容都已转换为的函数指针void*char*指针来执行此操作更加困难。

这样做的效果是,在实践中,C 风格的调用qsort与 C++ 风格的调用相比,std::sort可以为std::sort.

qsort在对随机排列的整数进行排序的极其简单的情况下,大约比 慢 2 倍,如此处std::sort所示。

检查实际的汇编代码输出主要是一个细节,工作量大,收效甚微。以具体的现实世界为例,您可以了解影响的真正程度。

clang、gcc 和 MSVC 的所有 3 个都能够std::sort比它们的qsort. 由于这是一个简单的优化,而将函数指针优化为内联调用不是,你会期望更少的主要编译器不会比这更好qsort

于 2016-11-25T17:36:39.493 回答
18
  1. 我们如何验证函数对象实际上是内联的?我们可以在实践中验证这一点吗?

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

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

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

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


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

IMO “函数对象是内联的”应该更好地阅读(或听到,我不知道该引用来自哪里):

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

于 2016-11-25T17:31:06.837 回答
1

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

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

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

于 2016-11-29T20:21:13.283 回答