将lambdas/functions存储在std::vector中,而不使用std::function
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 捕获允许我将变量发送到函数而不更改函数的签名)或能够存储成员函数以便我可以访问对象的属性。
现在,我尝试了几件事来使这个系统工作:
我试图将所有内容存储在
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
的第二个模板参数)。
但是,您可以存储指向 lambda 的智能指针,也许可以使用std::unique_ptr<std::function<void(void)>>
您确实需要管理这些 lambda 的生存期。
问题:
std::function
似乎每次循环迭代都会分配和释放内存,这对我来说真的很关键,
你真的确定吗?你真的对标吗?在许多情况下,它对您来说足够快(性能问题可能在其他地方)。
我不认为对于游戏渲染来说,瓶颈会是你今天认为的地方。您需要分析整个游戏。当然,出于基准测试目的,您需要启用编译器优化。另请参阅此内容(并点击那里的链接)。
典型的堆分配(具有::operator new
或malloc
...)通常需要不到一微秒(但有时更多)。在大多数情况下(但不是全部),这不是性能问题。
(我想要一个包含所有函数的 std::vector)
这很容易。创建一个标记的联合类型,也许使用std::variant
,然后std::vector
此类类型。或者,如果你有一个指针向量,创建一个公共超类(带有一些虚函数),并有一个指向该类的指针向量。
- Confusion: decltype vs std::function
- 为什么 std::function 可以作为 std::not2 的参数?
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- 传递给std::function template的template参数究竟代表什么
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 将函数包装器转换为 std::function
- 类型擦除的std::function与虚拟函数调用的开销
- C++ std::function 对于类 exept 的所有实例都是空的(只有 Visual2019 编译器问题)
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将 lambda 表达式传递给 std::function in C++
- 模板类的部分模板专用化,如 std::function
- 可变参数模板参数扩展 类型为 std::function 的类成员
- 从 std::function in C++ 访问模板化 lambda
- 什么是 std::function::argument_type 的替代品?
- C++派生类重载函数(带有 std::function 参数)不可见
- 如何在 qi 符号表中使用 std::function
- 将 std::function 与模板一起使用
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 我需要在 std::function 上使用 unique_ptr 吗?
- 如何将函数指针从 std::function 传递到 Linux 克隆?