我正在使用GameMaker Studio,您可以将其视为一个巨大的循环。
我使用计数器变量step
来跟踪它是什么帧。
为了提高效率,我希望每隔一个步骤运行一些代码。
if step mod 60 {
}
每60步(或以60 fps为1秒)运行该块。
我的理解是模数是一个繁重的操作,但我想象计算可能会失控。有没有更有效的方法来做到这一点?
也许涉及按位运算符?
我知道这可以适用于所有其他框架:
// Declare
counter = 0
// Step
counter = (counter + 1) & 1
if counter {
}
或者即使数字很大,模数对60FPS的性能影响也可以忽略不计?
答案 0 :(得分:3)
本质上:
i := 0
WHILE i < n/4
do rest of stuff × 4
do stuff that you want to do one time in four
Increment i
Do rest of stuff i%4 times
这个变量采用模数和基于它的开关,称为Duff的设备。哪个更快将取决于您的架构:在许多RISC芯片上,mod在单个时钟周期内执行,但在其他CPU上,整数除法甚至可能不是本机指令。
如果您本身没有循环计数器,因为它是一个事件循环,例如,您可以在执行代码的if块中每隔四次重置一次并重置它:
i := 1
WHILE you loop
do other stuff
if i == 4
do stuff
i := 1
else
i := i + 1
这是一个例子,两次做一些东西,三次做一次:
WHILE looping
do stuff
do stuff a second time
do stuff B
do stuff a third time
do stuff C
do stuff a fourth time
do stuff B
do stuff a fifth time
do stuff a sixth time
do stuff B
do stiff C
请注意,您所做的事情可能包括调用一次事件循环。
由于这可能变得难以处理,您可以使用模板元编程在C ++中为您编写这些循环,如:
constexpr unsigned a = 5, b = 7, LCM_A_B = 35;
template<unsigned N>
inline void do_stuff(void)
{
do_stuff_always();
if (N%a)
do_stuff_a(); // Since N is a compile-time constant, the compiler does not have to check this at runtime!
if (N%b)
do_stuff_b();
do_stuff<N-1>();
}
template<>
inline void do_stuff<1U>(void)
{
do_stuff_always();
}
while (sentinel)
do_stuff<LCM_A_B>();
但是,一般情况下,如果您想了解优化是否有帮助,请进行分析。
答案 1 :(得分:2)
答案中最重要的部分是:在上下文中,测试可能花费的时间非常少,以至于不值得离开大脑的离子来思考它。 如果它只花费1%,几乎可以肯定你应该考虑更大的加速比。
但是,如果循环很快,你可以输入这样的东西:
if (--count < 0){
count = 59;
// do your thing
}
在某些硬件中,该测试归结为单个指令递减和分支 - 如果否定。