Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are functors actually faster than pointers to functions?

According to Scott Meyers, one area where C++ shines over C is that function objects are faster than function pointers. He says this is because function objects are inlined, which increases speed.

I have two questions about this:

  1. How can we verify that function objects are, in fact, inlined? Can we verify this in practice?

  2. Does the inlining of function objects depend on the compiler we use, or do all compilers behave like this?

like image 450
user7140484 Avatar asked Nov 25 '16 17:11

user7140484


People also ask

What is the difference between a functor and a function pointer Why might we want to use a functor instead of a function pointer?

A function pointer allows a pointer to a function to be passed as a parameter to another function. Function Objects (Functors) - C++ allows the function call operator() to be overloaded, such that an object instantiated from a class can be "called" like a function.

What is the advantage of Replaceing function pointers Withh functors?

You often use functors instead - that is, classes that overload the operator () , so that they can be "called" as if they were functions. Functors have a couple of big advantages over function pointers: They offer more flexibility: they're full-fledged classes, with constructor, destructor and member variables.

Why do we use functors?

Functors give you more flexibility, at the cost of usually using slightly more memory, at the cost of being more difficult to use correctly, and at the cost of some efficiency.

Why do we need functors in C++?

A C++ functor (function object) is a class or struct object that can be called like a function. It overloads the function-call operator () and allows us to use an object like a function.


2 Answers

The C++ and C standards leaves a bunch of freedom to compilers. Compilers are free to count to 1 billion between every instruction, or only do so if an integer has a prime value in it.

Decent "real" compilers don't do this. This is a quality of implementation issue.

Inlining function objects into something like std::sort is something that every real compiler does. It is exceedingly easy to detect what needs to be inlined in those cases, because the type information carries with it the code needed to be inlined.

Doing so with a function pointer is harder. Doing so with a function pointer where everything has been converted to void* or char* pointers is even harder.

The effect of this is that, in practice, a C-style call to qsort vs a C++-style call to std::sort can result in an large advantage for std::sort.

qsort is roughly 2x slower than std::sort, as shown here, in a ridiculously simple situation of sorting randomly arranged integers.

Inspecting the actual assembly code output is mainly a detail, and it is a lot of work for little return. Taking concrete real-world examples gives you an idea of how big the impact really is.

All 3 of clang, gcc and MSVC where able to make std::sort be significantly faster than their qsort. And as this is an easy optimization, while optimizing function pointers into inline calls is not, you'd expect less major compilers to be no better than this at qsort.

like image 103
Yakk - Adam Nevraumont Avatar answered Oct 02 '22 16:10

Yakk - Adam Nevraumont


  1. How can we verify that function objects are in fact inlined? Can we verify this in practice?

Sure, inspect the finally emitted assembler code.

  1. The inlining function objects depends on the compiler we use, or all compilers behave like that?

It heavily depends on compiler implementation and optimization level used.
So no, there's no guarantee particular compilers (linkers) behave so.

Calls through function pointers cannot be inlined though.


According to him, function objects are inlined, so there is an increase in speed.

IMO "function objects are inlined" should better read (or heard, I don't know where that cite is from):

function objects can be inlined while calls through function pointers cannot.

like image 45
πάντα ῥεῖ Avatar answered Oct 02 '22 17:10

πάντα ῥεῖ