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

  • 相关阅读:
    前台js的复制与粘贴
    idea
    前台 js easyUI datagrid 杂记 验证(disable)
    《命运赋》
    前台
    js 、 java去除字符串中的数字
    【 协议 】 freemodbus的分层结构分析
    王爽 汇编11.10(2)编程用串传送指令,将F000H段中最后的16个字节复制到data段中
    王爽 汇编11.10(1)编程用串传送指令,将data段中的第一个字符串赋值到它后面的空间中
    汇编语搜索言中32位CPU多出的两个FS、GS段寄存器,全称是什么啊?
  • 原文地址:https://www.cnblogs.com/zhuyp1015/p/2635232.html
Copyright © 2020-2023  润新知