- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
请记住,我正在努力使代码尽可能快,因此包含分配或其他慢速代码的建议并不是真正的选择。
我有一个正在构建的游戏的渲染系统,我试图将所有渲染过程存储在一个函数 vector 中,例如:
if(Monster.IsAlive)
{
PushRender([...](){ // "..." means some stuff that I need to capture
// Rendering the monster here...
});
}
在每个循环结束时,我遍历我存储的所有渲染并渲染它们,之后我清除数组。
我希望能够拥有一个包含多个不同函数的 vector ,并且能够访问本地变量或复制到函数中的变量(例如,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();
}
}
最佳答案
so suggestions that contain allocations or other slow code is not really an option.
这显示了一种误解。分配不一定慢。避免堆分配的代码并不总是很快。您可以提供自己的 allocators (大多数标准 containers 有一个可选的分配器模板参数,例如 std::vector
的第二个模板参数)如果你相信你可以做得更快。
但是,您可以存储指向 lambda 的智能指针,也许使用 std::unique_ptr<std::function<void(void)>>
您确实需要管理这些 lambda 的生命周期。
Problem:
std::function
seem to allocate and deallocate memory every iteration of the loop, which is really critical to me,
你真的确定吗? 您真的进行了基准测试吗?在许多情况下,它对您来说已经足够快了(性能问题可能出在其他地方)。
我认为对于游戏渲染而言,瓶颈不会出现在您今天认为的位置。 您需要profile 你的整个游戏。当然,出于基准测试目的,您需要启用 compiler optimizations .另见 this (并点击那里的链接)。
典型的堆分配(使用 ::operator new
或 malloc
....)通常需要不到一微秒(但有时更多)。在大多数情况下(但不是全部),这不是性能问题。
(I want a single std::vector that contain all the functions)
这很容易。做一个tagged union类型,也许使用 std::variant
, 然后有一个 std::vector
这种类型的。或者,如果您有一个指针 vector ,创建一个公共(public)父类(super class)(带有一些虚函数)并有一个指向该类的指针 vector 。
关于c++ - 在没有 std::function 的情况下将 lambdas/函数存储在 std::vector 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48064433/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!