[英]Store lambdas/functions in std::vector without std::function
切記,我正在嘗試使代碼盡可能快,因此包含分配或其他慢速代碼的建議實際上不是一種選擇。
我有一個正在構建的游戲的渲染系統,並且試圖將所有渲染過程存儲在功能向量中,例如:
if(Monster.IsAlive)
{
PushRender([...](){ // "..." means some stuff that I need to capture
// Rendering the monster here...
});
}
在每個循環的末尾,我都要檢查存儲的所有渲染,然后渲染它們,然后清除數組。
我希望有一個包含多個不同函數的向量,並能夠訪問局部變量或復制到函數中的變量(例如,lambda capture讓我在不更改函數簽名的情況下將變量發送給函數)或能夠存儲成員函數,以便我可以訪問對象的屬性。
現在,我嘗試了幾種方法來使該系統正常工作:
我試圖將所有內容存儲在std::vector<std::function<void()>>
:
問題 : std::function
似乎在循環的每次迭代中都分配和取消分配內存,這對我來說確實很關鍵,因此std::function
並不是一個選擇,除非我能找到一個在不影響性能的情況下使用它的原因。
使用std::vector<void(*Render)()>
嘗試過:
問題 :我不能將lambda與該選項一起使用,也不能將成員函數與這些一起使用(至少我不能)。 因此,只有非成員函數才是我的問題。
我想要的系統內容:
std::vector
) 有人知道如何實施這樣的系統嗎?
如果我的解釋不夠好,請舉一個例子:
using Func = ...; // std::function<void()> for example
std::vector<Func> Functions;
while(Running)
{
// clear all the rendering
Functions.clear();
if(Monster.IsAlive)
{
// 1.
Functions.push_back(Monster.Render); // Monster.Render = Function
// Or 2.
Functions.push_back(RenderMonster); // RenderMonster = Function
// Or 3.
Functions.push_back([] () {
RenderImage(MonsterImage, X, Y);
//....
});
}
//... More code here
// Render everything that is saved so far
for(Func func : Functions)
{
func();
}
}
因此,包含分配或其他慢代碼的建議實際上不是一個選擇。
這顯示了一個誤解。 分配不一定很慢。 避免堆分配的代碼並不總是很快。 如果您認為可以做得更快,則可以提供自己的分配器 (大多數標准容器都有一個可選的分配器模板參數,例如std::vector
的第二個模板參數)。
但是,您可以使用std::unique_ptr<std::function<void(void)>>
存儲指向lambda的智能指針。
您確實需要管理這些Lambda的生存期。
問題:
std::function
似乎在循環的每次迭代中都分配和釋放內存,這對我來說真的很關鍵,
你真的確定嗎? 你真的基准了嗎? 在許多情況下,它對您來說足夠快(並且性能問題可能在其他地方)。
我認為對於游戲渲染而言,瓶頸不會像今天那樣。 您需要配置整個游戲。 當然,出於基准測試目的,您需要啟用編譯器優化 。 另請參見本 (並按照鏈接那里)。
典型的堆分配(使用::operator new
或malloc
....)通常花費不到一微秒的時間(但有時要多得多)。 在大多數情況下(但不是全部),這不是性能問題。
(我想要一個包含所有功能的std :: vector)
這很容易。 使用std::variant
一個標記的聯合類型,然后使用此類std::vector
。 或者,如果您有一個指針向量,則創建一個公共的超類(帶有一些虛函數)並具有一個指向該類的指針向量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.