简体   繁体   中英

c++ combining function pointers with best possible performance

I want to have a type describing a function that would allow creating new functions of the same type by combining existing functions, something like this:

FuncType f;
FuncType g;
FuncType h = f(g);
FuncType e = f + g;

I tried the using function pointers and assigning lambdas to them as follows:

typedef double(*FunPtr)(double);

double Fun1(double a) { return 2 * a; }
double Fun2(double a) { return a * a; }

int main{

  auto Fun3 = [](double a){return -a;};

  FuncType F1 = Fun1;
  FuncType F2 = Fun2;
  FuncType F3 = Fun3;

  auto HFun = [](double a){return (*F1)(a);} // does not work, requires capturing F1
  auto HFun = [F1](double a){return (*F1)(a);} // works
  FunPtr H = HFun; //Does not work, I suppose because of capturing F1.

}

Replacing

typedef double(*FunPtr)(double);

with

typedef std::function FunPtr;

solves the issue, but the function calls are going to happen inside very large nested loops, hence performance can be an issue and I have read here and there that using std::function comes with an overhead.

1- Is there a way to make this possible in a way that has a better performance compared to std::function?

2- Does using function pointers have a better performance in the first place?

3- Which of normal functions or lambdas is a better choice to start with? (F3 vs F1)

Thanks a lot!

1- Is there a way to make this possible in a way that has a better performance compared to std::function?

std::function is very flexible, but it is indeed slow. In order to be so flexible it performs type erasure and that has a cost. I would guess that probably all other options are faster than std::function (always benchmark).

2- Does using function pointers have a better performance in the first place?

Function pointers are very direct and the overhead should be negligible, but they are not very flexible.

3- Which of normal functions or lambdas is a better choice to start with? (F3 vs F1)

Lambda functions are much easier to use than than function pointers and they are efficient. But each lambda function is is "own type", which causes difficulties when you want to create an array of them.

Lambda functions can be converted to function pointers, but only if they do not capture , but you need to capture to do the f(g) you want. Therefore, in your case they don't seem to be an option

My suggestion is that you try to keep using function pointers and if you can't for some reason then change to using virtual classes.


In the past I had a need to store an array of functions and I started using an array of std::function which proved to be slow. In the end I changed to an array of base class pointers where the base class had a pure virtual method with the actual function to be implemented in subclasses. Benchmark showed that this solution was faster than using std::function . Even though virtual methods also have some overhead it was less than the overhead in std::function .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM