小重复算术与创建新变量 我在C++中编写了一个低规格的设备(~3MB RAM,~70MHz CPU),我想知道哪个更有效地运行(以及多少)。这是一段简化的代码,每秒将运行120-600次: void checkCollisions(int x, int y) { int p1x = x, p1y = y+2; int p2x = x, p2y = y+3; int p3x = x+3, p3y = y+3; // And so on... if (wallAt(p1x-1, p1y) || wallAt(p2x-1, p2y)) setCollision(LEFT, true); if (wallAt(p1x, p1y) || wallAt(p4x, p4y) || wallAt(p5x, p5y)) inGround = true; else inGround = false; // And so on... }

小重复算术与创建新变量 我在C++中编写了一个低规格的设备(~3MB RAM,~70MHz CPU),我想知道哪个更有效地运行(以及多少)。这是一段简化的代码,每秒将运行120-600次: void checkCollisions(int x, int y) { int p1x = x, p1y = y+2; int p2x = x, p2y = y+3; int p3x = x+3, p3y = y+3; // And so on... if (wallAt(p1x-1, p1y) || wallAt(p2x-1, p2y)) setCollision(LEFT, true); if (wallAt(p1x, p1y) || wallAt(p4x, p4y) || wallAt(p5x, p5y)) inGround = true; else inGround = false; // And so on... },c++,performance,algorithm,memory,memory-efficient,C++,Performance,Algorithm,Memory,Memory Efficient,或用其定义替换整数: void checkCollisionsAlt(int x, int y) { if (wallAt(x-1, y+2) || wallAt(x-1, y+3)) setCollision(LEFT, true); if (wallAt(x, y+2) || wallAt(x+3, y) || wallAt(x+2, y)) inGround = true; else inGround = false;

或用其定义替换整数:

void checkCollisionsAlt(int x, int y)
{
    if (wallAt(x-1, y+2) || wallAt(x-1, y+3))
        setCollision(LEFT, true);
    if (wallAt(x, y+2) || wallAt(x+3, y) || wallAt(x+2, y))
        inGround = true;
    else
        inGround = false;
    // And so on...
}
下面是示例的示意图:


第一个更容易理解,但我希望使用更多的内存。它有多大的区别?

如果机器以70 MHz的频率运行,这意味着每600秒有117000次循环

如果每个指令平均需要10个周期,它可以在600秒内执行11700条指令

当我查看您的代码时,我估计大约有100条指令可以执行它。 100/11700=运行此代码所花费时间的大约1%

您可以在汇编语言级别逐步了解它需要多少指令,但这可能不会有多大区别


我怀疑你在别处还有更重要的事情要做。

有几点需要考虑:

  • 如果完整版本也没有任何递归,那么就不用担心堆栈上的变量(p1x等)
  • 堆栈消耗是短暂的,除非您有病态代码,比如每帧都很重的深度递归,否则不会影响您
  • 在内存预算紧张的情况下,递归通常是个坏主意
  • 将它们显式命名为变量并不意味着它们在执行时会如此
  • 任何像样的编译器都可能识别变量的生命周期,并将它们推送到寄存器。请用当前正在使用的编译器优化级别来验证这一点,并在需要时考虑将其颠簸。
  • 此外,p1x等的这些值的预期范围是什么?为什么不使用短int

    堆栈内存增长的短暂性意味着您的峰值堆内存不会受到影响。堆栈可以增长和收缩,这取决于堆栈的布局和预算数量,您可能根本不必担心这一点


    注意:任何和所有堆分配都需要仔细检查。尝试实现自定义分配器,而不是产生标准的malloc()块开销。当然,您在问题中没有提到堆,但是,有一件事需要记住。

    如果编译器按照您希望的方式工作,那么让代码更快的是将所有变量放入寄存器。我认为任何现代编译器都会从自己的角度理解,您的两个代码版本是相同的,并且会给出相同或非常相似的输出。在这两种情况下,它都会尝试使用核心寄存器,并且只有在没有足够数量的寄存器可用时,才会使用内存堆栈。如果编译器允许您选择保留中间程序集文件,那么您就可以深入了解代码和性能。请记住,低内存访问—使用寄存器—将提高代码性能。

    唯一可能的答案是:对两者进行编码并进行比较。关于比较代码,一种方法是编译(有优化和没有优化)汇编程序代码并进行比较。通过执行
    inGround=wallAt可以节省一些指令(p1x,p1y)|瓦拉特(p4x,p4y)|瓦拉特(p5x,p5y)
    分析代码比在网上征求意见更能了解代码的性能。我的投票结果是,这无关紧要,因为优化编译器会将它们编译成相同的汇编代码。还有近100种其他小情况稍微相似,所以我认为最好在编写东西时改变我的编码方式同样,我选择了最好的一个。因此,尽管这个单独的场景不占用大量的CPU时间,但问题仍然很重要。@RandomPerson323:好的,那么让我给你一些建议,你可以接受也可以不接受。这不是你事先做的事情。让代码运行,然后使用。它将准确地告诉您应该担心什么,这几乎肯定不是您现在所关心的。整数的预期范围将达到32768。经过一些修改,它可能会很短。