函數式編程的便利在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依然是一個可選項。