lambda功能比分离的方法慢

发布于 2025-02-13 12:40:33 字数 2779 浏览 1 评论 0原文

了解lambda在C ++中的开销11 c ++ 0x lambda开头。但是,第一个是Fluke,第二个是将其与功能对象进行比较。

我正在使用lambda和分离的函数来检查一个函数的函数(以下代码)的函数的性能(Compiler:G ++;标准:C ++ 17)。使用多个输入检查时,LAMBDA功能在系统上较慢,在运行时大约增加3%。代码附加在下面。

编译器是否有可能优化对分离方法的调用,但对lambda表达式不进行相同的操作?

#include <vector>
#include <iostream>
#include <chrono>

using namespace std;


template <
    class result_t   = std::chrono::milliseconds,
    class clock_t    = std::chrono::steady_clock,
    class duration_t = std::chrono::milliseconds>
auto since(std::chrono::time_point<clock_t, duration_t> const& start)
{
    return std::chrono::duration_cast<result_t>(clock_t::now() - start);
}

int manhattanDistance(int x1, int y1, int x2, int y2) {
    return abs(x1 - x2) + abs(y1 - y2);
}

int fWithoutLambda(int x, int y, vector<vector<int>>& points) {
    int min_d = numeric_limits<int>::max();
    int idx = -1;
    
    for (int i = 0; i < points.size(); i++) {
        auto d = manhattanDistance(x, y, points[i][0], points[i][1]);
        if ((x == points[i][0] || y == points[i][1]) && d < min_d) {
            idx = i;
            min_d = d;
        }
    }
    
    return idx;
}

int fWithLambda(int x, int y, vector<vector<int>>& points) {
    auto manh = [x, y](int x2, int y2) {return abs(x - x2) + abs(y - y2);};
    
    int min_d = numeric_limits<int>::max();
    int idx = -1;
    
    for (int i = 0; i < points.size(); i++) {
        auto d = manh(points[i][0], points[i][1]);
        if ((x == points[i][0] || y == points[i][1]) && d < min_d) {
            idx = i;
            min_d = d;
        }
    }
    
    return idx;
}

int main() {

    size_t repeats = 10;
    int time_no_lambda{0};
    int time_lambda{0};

    for (size_t j = 0; j < repeats; ++j) {
        int n = 1000000;
        vector<vector<int>> v(n);
        int counter = 0;
        for (auto& el : v) {
            v[counter++] = {counter, counter%10};
        }

        int x = 10, y = 5;

        auto start = std::chrono::steady_clock::now();  
        fWithLambda(x, y, v);
        auto tim_0 = since(start).count();
        time_lambda += tim_0;
        fWithoutLambda(x, y, v);
        time_no_lambda += (since(start).count() - tim_0);
    }

    std::cout << "Elapsed(ms), lambda =" << (time_no_lambda/repeats) << std::endl;  
    std::cout << "Elapsed(ms), no lambda =" << (time_lambda/repeats) << std::endl;  
}

Similar questions have been addressed in Understanding the overhead of lambda functions in C++11 and C++0x Lambda overhead. However the first one was a fluke and the second is comparing it with function objects.

I am checking performance (compiler: g++; standard: c++17) of a function computing a simple distance (code below) using both a lambda and a separated function. The lambda function is systematically slower, by about 3% in runtime when checking with multiple inputs. Code attached below.

Is there any possibility that the compiler is optimizing calls to the separated method but not doing the same with the lambda expression?

#include <vector>
#include <iostream>
#include <chrono>

using namespace std;


template <
    class result_t   = std::chrono::milliseconds,
    class clock_t    = std::chrono::steady_clock,
    class duration_t = std::chrono::milliseconds>
auto since(std::chrono::time_point<clock_t, duration_t> const& start)
{
    return std::chrono::duration_cast<result_t>(clock_t::now() - start);
}

int manhattanDistance(int x1, int y1, int x2, int y2) {
    return abs(x1 - x2) + abs(y1 - y2);
}

int fWithoutLambda(int x, int y, vector<vector<int>>& points) {
    int min_d = numeric_limits<int>::max();
    int idx = -1;
    
    for (int i = 0; i < points.size(); i++) {
        auto d = manhattanDistance(x, y, points[i][0], points[i][1]);
        if ((x == points[i][0] || y == points[i][1]) && d < min_d) {
            idx = i;
            min_d = d;
        }
    }
    
    return idx;
}

int fWithLambda(int x, int y, vector<vector<int>>& points) {
    auto manh = [x, y](int x2, int y2) {return abs(x - x2) + abs(y - y2);};
    
    int min_d = numeric_limits<int>::max();
    int idx = -1;
    
    for (int i = 0; i < points.size(); i++) {
        auto d = manh(points[i][0], points[i][1]);
        if ((x == points[i][0] || y == points[i][1]) && d < min_d) {
            idx = i;
            min_d = d;
        }
    }
    
    return idx;
}

int main() {

    size_t repeats = 10;
    int time_no_lambda{0};
    int time_lambda{0};

    for (size_t j = 0; j < repeats; ++j) {
        int n = 1000000;
        vector<vector<int>> v(n);
        int counter = 0;
        for (auto& el : v) {
            v[counter++] = {counter, counter%10};
        }

        int x = 10, y = 5;

        auto start = std::chrono::steady_clock::now();  
        fWithLambda(x, y, v);
        auto tim_0 = since(start).count();
        time_lambda += tim_0;
        fWithoutLambda(x, y, v);
        time_no_lambda += (since(start).count() - tim_0);
    }

    std::cout << "Elapsed(ms), lambda =" << (time_no_lambda/repeats) << std::endl;  
    std::cout << "Elapsed(ms), no lambda =" << (time_lambda/repeats) << std::endl;  
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文