bind与lambda
bind() 和 lambda 表达式都可以实现类似的功能,在使用的时候有时候不知道选择哪一个。这里来做一个简单的总结。主要参考了一下的文章:
http://stackoverflow.com/questions/1930903/bind-vs-lambda
http://www.gockelhut.com/c++/articles/lambda_vs_bind
1. bind() 在多层嵌套的时候会使代码非常难看懂(参见文章一)
2. lambda 不支持“多态性”(其实就是泛型),需要在定义的时候指定参数类型
3. lambda 运行速度会比bind() 函数快很多
4. lambda 可以通过 std::function 实现“多态”特性
下面是一个例子,表明lambda 的运行时间比bind 的情况要快很多:
#include <cstdint> #include <chrono> #include <iostream> #include <string> #include <functional> #include <thread> 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; }; 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 = 100000) { for (uint64_t i = 0; i < upper_limit; ++i) func(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_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; } 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; } int main() { 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 (bind_auto) ", &test_accumulate_bind_auto); return 0; }
运行结果:
C:\Windows\system32\cmd.exe /c lambda_vs_bind.exe
Accumulate (lambda) 20001
Accumulate (bind) 110007
Accumulate (bound lambda) 50003
Accumulate (bind_auto) 90005
Hit any key to close this window...
从运行结果可以看出,使用lambda比bind快一个数量级,使用auto 修饰函数对象比用std::function<>速度也略有提升。
make it simple, make it happen