是std :: function比自动存储lambda函数重

是std :: function比自动存储lambda函数重

问题描述:

我听说std::function的成本要比auto重,以处理lambda函数.有效的现代C ++项目5.我想要的是通过一些示例代码来阐明为什么std::function使用比auto更多的内存的机制. 有人可以帮我吗?

I heard that cost of std::function is heavier than auto to deal with a lambda function. effective modern c++ item5. What I want is to clarify the mechanism why std::function use more memory than auto with some sample code. Could somebody help me?

编辑

class Widget {
public:
  Widget(int i) : i_(i) {}
  bool operator<(const Widget& o) { return o.value() > i_; }
  int value() const { return i_; };
private:
  int i_;
  int dummy_[1024];
};

int main() {
  // performance difference between auto and std::function
  { 
    auto less1 = [](const auto& p1, const auto& p2) {
      return *p1 < *p2;
    };
    std::cout << "size of less1: " << sizeof(less1) << endl;

    function<bool(const std::unique_ptr<Widget>&,
                  const std::unique_ptr<Widget>&)>
        less2 = [](const std::unique_ptr<Widget>& p1,
                   const std::unique_ptr<Widget>& p2) {
          return *p1 < *p2;
        };
    std::cout << "size of less2: " << sizeof(less2) << endl;

    {
      // auto
      std::vector<std::unique_ptr<Widget>> ws1;
      for (auto i = 0; i < 1024*100; ++i) {
        ws1.emplace_back(new Widget(std::rand()));
      }

      auto start = std::chrono::high_resolution_clock::now();
      std::sort(ws1.begin(), ws1.end(), less1);
      auto end = std::chrono::high_resolution_clock::now();
      cout << ws1[0].get()->value() << " time: " << (end - start).count() << endl;
    }

    {
      // std::function
      // 25% slower than using auto
      std::vector<std::unique_ptr<Widget>> ws2;
      for (auto i = 0; i < 1024*100; ++i) {
        ws2.emplace_back(new Widget(std::rand()));
      }

      auto start = std::chrono::high_resolution_clock::now();
      std::sort(ws2.begin(), ws2.end(), less2);
      auto end = std::chrono::high_resolution_clock::now();
      cout << ws2[0].get()->value() << " time: " << (end - start).count() << endl;
    }
  }
  return 0;
}

它来自 https://github.com/danielhongwoo/mec/blob/master/item5/item5.cpp

我认为这段代码显示使用std::function的速度比使用auto慢.但是不占用内存.我只是想用一些真实的代码来证明这一点.

I think this code shows me using std::function is slower than using auto. But not usage of memory. I just want to prove it with some real code.

std::function可以存储任意可调用对象.因此必须从事类型擦除才能存储任意类型的东西.在一般情况下,这可能需要动态分配,并且在每次调用operator ()时,肯定需要间接调用(虚拟调用或通过函数指针的调用).

std::function can store an arbitrary callable. In therefore has to engage in type erasure to be able to store something of an arbitrary type. This can require dynamic allocation in the general case, and it definitely requires an indirect call (either a virtual call or a call through a function pointer) on each invocation of operator ().

lambda表达式的类型为 std::function,它是定义了operator()的未命名类类型(lambda的闭包类型).使用auto a存储lambda可使a的类型成为精确的关闭类型,而没有开销.

The type of a lambda expression is not std::function, it's an unnamed class type with operator() defined (the lambda's closure type). Using auto a to store a lambda makes the type of a this precise closure type, which has no overhead.