c++11 lambda 的效率

来源:互联网 发布:百度移动优化排名技术 编辑:程序博客网 时间:2024/05/16 12:50

c++11新特性lambda函数的效率测试

       在使用到c++ stl中算法的时候,很多情况下需要传入函数对象或函数指针,根据effective stl书中的描述,传递函数对象运行效率要比函数指针高。原因是算法函数中可以根据函数对象内联展开调用的函数,而当传入函数指针时,这种内联展开的技术不可能实现,因此存在大量函数调用的情况。

       c++11新特性中提供了lambda函数,lambda函数是一种匿名函数具体可参见c++11维基百科的解释。本文主要讨论的是,当使用lambda函数时,编译器到底是怎么处理的,1、像是函数对象那样,可以内联展开,还是2、像函数指针那样,一定要进行函数调用实现呢?

       我们使用的是code::blocks IDE,它提供一个程序运行计时的功能,在程序结束后打印出运行的时间,方便我们比较这三种情况下的程序耗时。三个测试代码均使用了-O2优化。lambda的测试代码如下:

int main(){    vector<int> vInt;    const int SIZE_VECTOR = 10000000;    for (int i = 0; i < SIZE_VECTOR; ++i)    {        vInt.push_back(i);    }    for (int i = 0; i < 100; ++i)    {        for_each(vInt.begin(), vInt.end(), [](int ele){ static long long sum = 0; sum += ele; });    }    return 0;}

       这个代码是纯测试使用,不具有很强的功能,使用静态变量sum是为了保证与函数指针与函数对象的内容一致。这段代码运行的时间约为:1.550s。每次运行的时间都不一样,但均在此值附近。

       下面测试使用函数对象的运行时间。代码如下:

struct SumUpOperator{    inline void operator ()(int ele){        static long long sum = 0;        sum += ele;    }};int main(){    vector<int> vInt;    const int SIZE_VECTOR = 10000000;    for (int i = 0; i < SIZE_VECTOR; ++i)    {        vInt.push_back(i);    }    for (int i = 0; i < 100; ++i)    {        for_each(vInt.begin(), vInt.end(), SumUpOperator());    }    return 0;}

       函数对象内,操作符()函数中的内容与lambda中的完全一致。运行时间为:1.600s。基本与使用lambda函数的情况相同。

       下面测试使用函数指针程序运行时间。代码如下:

inline void sumUp(int ele){    static long long sum = 0;    sum += ele;}int main(){    vector<int> vInt;    const int SIZE_VECTOR = 10000000;    for (int i = 0; i < SIZE_VECTOR; ++i)    {        vInt.push_back(i);    }    for (int i = 0; i < 100; ++i)    {        for_each(vInt.begin(), vInt.end(), sumUp);    }    return 0;}

       函数内容与之前的完全一致。运行时间为:4.550s。这比之前的两种情况要慢许多。

       如此可以说明,使用lambda函数的效率与使用函数对象是一样的,都要快于函数指针。他们都能够在编译期将代码内联展开,减少函数调用的时间。

       现在,终于可以放心使用lambda函数而不用担心效率问题了。

       最后,编译器实际上将lambda函数转化为一个函数对象,所以,它与使用函数对象是一样高效的。




0 0
原创粉丝点击