程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++ 11學習筆記--Lambda 表達式(對比測試Lambda ,bind,Function Object)

c++ 11學習筆記--Lambda 表達式(對比測試Lambda ,bind,Function Object)

編輯:C++入門知識

c++ 11學習筆記--Lambda 表達式(對比測試Lambda ,bind,Function Object)


所有c++ coder都應該為這個語法感到高興,說的直白一點,Lambda 表達式就是函數對象的語法糖。       還是直接看對比栗子吧,抄襲的是msdn的官網   該示例使用 for_each 函數調用中嵌入的 lambda 向控制台打印 vector 對象中的每個元素是偶數還是奇數。   使用lambda   復制代碼 #include <algorithm> #include <iostream> #include <vector> using namespace std;   int main()  {    // Create a vector object that contains 10 elements.    vector<int> v;    for (int i = 0; i < 10; ++i) {       v.push_back(i);    }      // Count the number of even numbers in the vector by     // using the for_each function and a lambda.    int evenCount = 0;    for_each(v.begin(), v.end(),[&evenCount] (int n) {       cout << n;       if (n % 2 == 0) {          cout << " is even " << endl;          ++evenCount;       } else {          cout << " is odd " << endl;       }    });      // Print the count of even numbers to the console.    cout << "There are " << evenCount          << " even numbers in the vector." << endl; } 復制代碼 使用Function Object   復制代碼 #include <algorithm> #include <iostream> #include <vector> using namespace std;   class FunctorClass { public:     // The required constructor for this example.     explicit FunctorClass(int& evenCount)          : m_evenCount(evenCount)     {     }       // The function-call operator prints whether the number is     // even or odd. If the number is even, this method updates     // the counter.     void operator()(int n) const     {         cout << n;           if (n % 2 == 0) {             cout << " is even " << endl;             ++m_evenCount;         } else {             cout << " is odd " << endl;         }     }   private:     // Default assignment operator to silence warning C4512.     FunctorClass& operator=(const FunctorClass&);       int& m_evenCount; // the number of even variables in the vector. };     int main()  {     // Create a vector object that contains 10 elements.     vector<int> v;     for (int i = 0; i < 10; ++i) {         v.push_back(i);     }       // Count the number of even numbers in the vector by      // using the for_each function and a function object.     int evenCount = 0;     for_each(v.begin(), v.end(), FunctorClass(evenCount));       // Print the count of even numbers to the console.     cout << "There are " << evenCount          << " even numbers in the vector." << endl; } 復制代碼 正如微軟文檔所言,這兩種在效率上並沒有實質性的差距,我自己也測試了,不管在debug模式下還是release模式下,果然沒有差距。   無意中我在晚上發現了bind和Lambda對比測試,前三種方式是網上的,後面兩種是我自己加的,結果絕對讓我蛋碎了一地。   復制代碼 #include <cstdint> #include <chrono> #include <iostream> #include <string> #include <thread> #include <vector> #include <algorithm>   #if USE_BOOST #include <boost/function.hpp> #include <boost/bind.hpp> #endif     class FunctorClass { public:     // The required constructor for this example.     explicit FunctorClass(uint64_t& evenCount)     : m_evenCount(evenCount)     {     }          // The function-call operator prints whether the number is     // even or odd. If the number is even, this method updates     // the counter.     void operator()(int n) const     {          m_evenCount += n;     }      private:     // Default assignment operator to silence warning C4512.     FunctorClass& operator=(const FunctorClass&);          uint64_t& m_evenCount; // the number of even variables in the vector. };   class timer { public:     typedef std::chrono::high_resolution_clock clock;     typedef clock::time_point                  time_point;     typedef clock::duration                    duration;      public:     timer()     {         reset();     }          void reset()     {         _starttime = clock::now();     }          duration elapsed() const     {         return clock::now() - _starttime;     } protected:     time_point _starttime; };   bool test_timer() {     using std::chrono::milliseconds;     typedef timer::duration duration;          const milliseconds sleep_time(500);          timer t;     std::this_thread::sleep_for(sleep_time);     duration recorded = t.elapsed();          // make sure the clock and this_thread::sleep_for is precise within one millisecond (or at least in agreement as to     // how inaccurate they are)     return (recorded - milliseconds(1) < sleep_time)     && (recorded + milliseconds(1) > sleep_time); }   template <typename T> void volatile_write(const T& x) {     volatile T* p = new T;     *p = x;     delete p; }   template <typename Function> void run_test(const std::string& name, Function func) {     std::cout << name;     timer t;     volatile_write(func());     timer::duration duration = t.elapsed();     std::cout << '\t' << duration.count() << std::endl; }   template <typename Function> void do_test_loop(Function func, const uint64_t upper_limit = 100000000ULL) {     uint64_t i;     for (i = 0; i < upper_limit; ++i)         func(i);     if(i == upper_limit)     {         std::cout<<i;     } }   uint64_t test_accumulate_lambda() {     uint64_t x = 0;     auto accumulator = [&x] (uint64_t i) { x += i;  };     do_test_loop(accumulator);     return x; }   void test_accumulate_bind_function(uint64_t& x, uint64_t i) {     x += i; }   uint64_t test_accumulate_bind() {     namespace arg = std::placeholders;          uint64_t x = 0;     std::function<void (uint64_t)> accumulator = std::bind(&test_accumulate_bind_function, std::ref(x), arg::_1);     do_test_loop(accumulator);     return x; }   uint64_t test_accumulate_bound_lambda() {     uint64_t x = 0;     std::function<void (uint64_t)> accumulator = [&x] (uint64_t i) { x += i; };     do_test_loop(accumulator);     return x; }     uint64_t test_accumulate_class_function() {     uint64_t x = 0;       do_test_loop(FunctorClass(x));    // for_each(v.begin(), v.end(), FunctorClass(x));     return x; }   uint64_t test_accumulate_bind_auto() {     namespace arg = std::placeholders;          uint64_t x = 0;     auto accumulator = std::bind(&test_accumulate_bind_function, std::ref(x), arg::_1);     do_test_loop(accumulator);     return x; }   #if USE_BOOST uint64_t test_accumulate_boost_bind() {     uint64_t x = 0;          boost::function<void (uint64_t)> accumulator = boost::bind(&test_accumulate_bind_function, boost::ref(x), _1);     do_test_loop(accumulator);     return x; }   uint64_t test_accumulate_boost_bound_lambda() {     uint64_t x = 0;     boost::function<void (uint64_t)> accumulator = [&x] (uint64_t i) { x += i; };     do_test_loop(accumulator);     return x; } #endif   int main() {     if (!test_timer())     {         std::cout << "Failed timer test." << std::endl;         return -1;     }          run_test("Accumulate (lambda)            ", &test_accumulate_lambda);     run_test("Accumulate (bind)              ", &test_accumulate_bind);     run_test("Accumulate (bound lambda)      ", &test_accumulate_bound_lambda);     run_test("Accumulate (Function Object)    ", &test_accumulate_class_function);     run_test("Accumulate (bind auto)    ", &test_accumulate_bind_auto); #if USE_BOOST     run_test("Accumulate (boost bind)        ", &test_accumulate_boost_bind);     run_test("Accumulate (boost bound lambda)", &test_accumulate_bound_lambda); #endif } 復制代碼 debug模式:   Accumulate (lambda)            100000000  422885105   Accumulate (bind)              100000000   4346676523   Accumulate (bound lambda)      100000000 1707092933   Accumulate (class function)    100000000   494674507   Accumulate (bind auto)         100000000 3381097610       Release模式   Accumulate (lambda)            100000000  17978   Accumulate (bind)              100000000   607188485   Accumulate (bound lambda)      100000000 520421500   Accumulate (Function Object)    100000000  1925   Accumulate (bind auto)         100000000 1726

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved