許多主題告訴我們,使用像 lambda 運算式這樣的小??物件可以避免在使用std::function. 但我的研究表明并非如此。
這是我的實驗代碼,很簡單
#include <iostream>
#include <functional>
using namespace std;
typedef std::function<int(int, int)> FUNC_PROTO;
class Test
{
public:
int Add(int x, int y) { return x y; }
};
int main()
{
Test test;
FUNC_PROTO functor = [&test](int a, int b) {return test.Add(a, b); };
cout << functor(1, 2) << endl;
}
我在centos7上編譯它,gcc版本為4.8.5 20150623 但是valgrind顯示了這一點:
==22903== HEAP SUMMARY:
==22903== in use at exit: 0 bytes in 0 blocks
==22903== total heap usage: 1 allocs, 1 frees, 8 bytes allocated
即使我洗掉了參考捕獲,也只是一個普通的 lambda 函式。它仍然需要 1 位元組的堆分配。
我有什么不對的地方來優化小物件。
更新:
謝謝回復。我想我應該添加更多的實驗細節。
以消除可能引起參考捕獲的原因。我洗掉了捕獲,代碼如下:
FUNC_PROTO functor = [](int a, int b) {return a b; };
Valgrind 展示了這一點:
==16691== total heap usage: 1 allocs, 1 frees, 1 bytes allocated
仍然是 1 位元組的堆分配。
我也嘗試這樣做以消除 lambda 本身的可能影響(我認為不是)
FUNC_PROTO functor = [](int a, int b) {return a b; };
FUNC_PROTO functor2 = [](int a, int b) {return a * b; };
FUNC_PROTO test = nullptr;
for ( int i = 0; i < 10; i)
{
if (i % 2 == 0)
{
test = functor;
}
else
{
test = functor2;
}
}
Valgrind 顯示:
==17414== total heap usage: 12 allocs, 12 frees, 12 bytes allocated
這可以證明函子不是完全基于堆疊的物件。
這是我的構建腳本:
g test.cpp -o test -std=c 11 -g -O3 -DNDEBUG
這是我的 valgrind 腳本:
valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-leak-kinds=all ./test
uj5u.com熱心網友回復:
較早版本的 libstdc ,如 gcc 4.8.5 發布的版本,似乎只優化函式指標以不分配(如這里所示)。
由于std::function實作沒有您想要的小物件優化,您將不得不使用替代實作。無論是升級你的編譯器或使用boost::function,這在本質上是一樣的std::function。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/405192.html
標籤:
上一篇:C 11:將std::tuple型別轉換為void*并回傳
下一篇:分配期間沒有指標衰減的功能
