问题
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