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<>速度也略有提升。

 

posted @ 2012-08-12 17:00  KingsLanding  阅读(2581)  评论(1编辑  收藏  举报