C++ Lambda函数的讨论

来源:岁月联盟 编辑:exp 时间:2012-01-19
函数式编程的便利在Haskell的map中令人映象深刻,比如对一个列表[1,2,3,4,5,6,7,8,9,10] 的所有元素实施+1操作只需要
[plain]
map(+1)[1..10] 
就可以得到
 
[plain]
=> [2,3,4,5,6,7,8,9,10,11] 
 
有兴趣的可以到http://tryhaskell.org/ 尝试一下Haskell,非常优美的一门语言。
 
而C++也开始在新的标准中支持函数式编程,那么函数式编程究竟能带给我们什么? 性能 异或是 简洁?
 
(1)简洁,由一个最简单的例子来讨论函数式编程的,将vector<int> 容器vec_int 中每个元素的值+1.假设vec_int中存放的是1到10.
 
  一般C++程序的写法是(为了简洁使用了auto关键字):
 
[cpp]
for(auto it =vec_int.begin();it!=vec_int.end();++it) 
{   *it++ ; } 
 
          使用新标准的Lambda函数的方式是:
[cpp]
for_each(vec_int.begin() ,vec_int.end(),  [](int x){ x++;} ); 
 
         如果使用Boost库的方式,则是:
[cpp]
BOOST_FOREACH(int x,vec_int){   x++;    } 
 
         函数式编程的经典map-reduce模式(使用Haskell)应该是:
[plain]
map(+1)[1..10] 
 
那大家对新标准的Lambda函数带给我们的简洁性怎么看呢?我的观点是,简洁性(在处理此类问题)上
经典函数式编程> C++ Boost库的实现> C++新标准的Lambda实现> 原C++命令式编程
 
总的而言,C++期待的函数式编程尽管不如Haskell和LISP中那么给力,但还是给我们带来了编程的便利。C++中推荐大家尝试一下Boost库,因为BOOST_FOREACH不仅可以用于容器,一般数组也可以使用。
 
 
(2)性能
 
对于这一点而言,C++新标准还是给了我相当的惊喜,使用Lambda函数的性能居然高于手工命令式编程,就上面的+1简单例子,进行简单的测试代码如下
 
[cpp]
#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <boost/foreach.hpp> 
#include <time.h> 
 
using namespace std; 
 
int main() 

    vector<int> vec_int; 
    vec_int.reserve(10); 
    for(int i=0; i<10; ++i) 
    {   vec_int.push_back(i);} 
 
    /*每个循环 外层在循环times次*/ 
    int times = 100000; 
 
    clock_t start = clock(); 
    /***********************************************/ 
        for(int i=0; i<times;++i) 
        { 
            for_each(vec_int.begin() ,vec_int.end(),  [](int x){ x++;} ); 
        } 
    /**********************************************/ 
    clock_t finish = clock(); 
    cout<<"time used is : "<<finish-start<<"ms"<<endl; 
 
 
    start = clock(); 
    /***********************************************/ 
        for(int i=0; i<times;++i) 
        { 
            BOOST_FOREACH(int x,vec_int) 
            {   x++;    } 
        } 
    /**********************************************/ 
    finish = clock(); 
    cout<<"time used is : "<<finish-start<<"ms"<<endl; 
 
 
    start = clock(); 
    /***********************************************/ 
        for(int i=0; i<times;++i) 
        { 
            for(auto it =vec_int.begin();  
                it!=vec_int.end();++it) 
            {   *it++ ; } 
        } 
    /**********************************************/ 
    finish = clock(); 
    cout<<"time used is : "<<finish-start<<"ms"<<endl; 
 
 
    system("pause"); 
 
    return 0; 

 
在我的机子上测试结果如下:
 /
 
最快的是C++新标准的实现,第二是的BOOST_FOREACH,最慢的是命令式方式。我一直认为手工命令式方式应该是最快的,而结果则恰恰相反,所以容器的迭代,可以尝试多用用Lambda表达式了,当然Boost依然是一个可选项。