is std::function heavier than auto storing lambda function

守給你的承諾、 提交于 2019-12-23 10:02:41

问题


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?

edit

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;
}

it's from https://github.com/danielhongwoo/mec/blob/master/item5/item5.cpp

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.


回答1:


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 ().

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.




回答2:


The memory cost for std::function is true. As I tested on a RHEL 64bit machine, it is 32 bytes, while a lambda only takes 1 byte. But for runtime efficiency, the comments in the original cost cannot be reproduced.

With g++ -std=c++17 -O2, I got std::function much faster than lambda actually. With g++ -std=c++14 -O2, the results are close but lambda are still behind.

size of less1 as lambda: 1
size of less2 as function : 32
3722 time lambda sort: 47979086
6700 time function sort: 45291861


来源:https://stackoverflow.com/questions/48007520/is-stdfunction-heavier-than-auto-storing-lambda-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!