2

As I googled std::function works slower than simple lambda function.

Consider the following use case will there be std::function penalty when using stl sorting algorithms (v vector may be big enough and occupy about N*GB of data):

#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>

using namespace std;

void sorter(std::vector<int>& v, std::function<bool(int a, int b)> f){
    std::sort(v.begin(), v.end(), f);
}

int main()
{
    std::vector<int> v = {5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
    for (auto val : v)
        cout << val << " ";
    cout << endl;

    int c = 4;
    auto f = [&c](int a, int b){ return a+b < c; };
    
    sorter(v, f);

    for (auto val : v)
        cout << val << " ";
    cout << endl;

    return 0;
}

As you can see I create the lambda function f and pass it to a sorter function. My task is to keep sorter function non-templated that is why I tried to pass lamda function as std::function. Or are there better ways of doing that?

6
  • 2
    Since the lambda function is non-capturing, you could have the parameter accept a function pointer instead. Commented Aug 6, 2022 at 14:22
  • 2
    Non-captured lambdas can be converted to function pointers, so you can directly void sorter(std::vector<int>& v, bool(*f)(int, int)). Commented Aug 6, 2022 at 14:30
  • 2
    No, with a capture your options are to use a template or a std::function (or another type erasure similar to std::function). Commented Aug 6, 2022 at 14:59
  • 1
    You can create your own type erasure that is lighter weight than std::function. Example. Commented Aug 6, 2022 at 15:16
  • 1
    As far as I understand the performance issue, a template might be faster because the compiler is probably inline the code into the algorithm. In practice unless you have to sort large amount of data with trivial comparison, the overhead should not matter much. Commented Aug 6, 2022 at 15:41

1 Answer 1

3

Lambdas that do not capture anything can be converted to a function pointer with the + operator:

void sorter(std::vector<int>& v, bool (*cmp)(int,int));

int main() {
  auto const cmp = +[](int a, int b) { return a < b; };
  vector<int> v{3, 2, 1};
  sorter(v, cmp);
}

But if it does capture something, you should either make it a template, or use std::function. No way around that.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.