Functor vs Function Performance
Is there a performance difference between using functors and regular functions?
In general, functors and regular functions have similar performance characteristics in C++. However, there are a few factors that can affect their performance:
- Inlining: Functors defined inside a class can be easier for the compiler to inline compared to regular functions, especially if the functor is used in a template context. Inlining eliminates the function call overhead and can lead to better performance.
- Complexity: For simple operations, functors and regular functions should have comparable performance. However, if the functor contains additional data members or complex logic, it may introduce slight overhead compared to a simple function.
- Compiler optimizations: Modern compilers are quite good at optimizing both functors and regular functions. In many cases, the compiler can generate equally efficient code for both.
Here's an example comparing the performance of a functor and a regular function:
#include <algorithm>
#include <chrono>
#include <iostream>
#include <vector>
class Functor {
public:
int operator()(int x) const {
return x * 2;
}
};
int FuncDouble(int x) {
return x * 2;
}
int main() {
using namespace std::chrono;
std::vector<int> large_vec(10000000, 42);
auto start = high_resolution_clock::now();
std::transform(
large_vec.begin(), large_vec.end(),
large_vec.begin(), Functor());
auto end = high_resolution_clock::now();
duration<double> diff = end - start;
std::cout << "Functor time: "
<< diff.count() << " s\n";
start = high_resolution_clock::now();
std::transform(
large_vec.begin(), large_vec.end(),
large_vec.begin(), FuncDouble);
end = high_resolution_clock::now();
diff = end - start;
std::cout << "Function time: "
<< diff.count() << " s\n";
}
Functor time: 0.0221406 s
Function time: 0.0254901 s
In this example, we have a functor Functor
and a regular function FuncDouble
, both of which double their input. We use std::transform
to apply these callables to a large vector of integers and measure the execution time using std::chrono
.
On a typical modern compiler with optimizations enabled, the performance difference between the functor and the regular function should be negligible.
It's important to profile and measure performance in your specific use case to determine if using a functor or a regular function has any significant impact. In most cases, the choice between a functor and a function should be based on design considerations, such as the need for state or the desire for a function object, rather than performance concerns.
Function Objects (Functors)
This lesson introduces function objects, or functors. This concept allows us to create objects that can be used as functions, including state management and parameter handling.