我最近一直在研究欧拉项目,我想我也可以模块化地解决这些问题,这样我就可以将这些功能添加到我的个人库中。当我使代码模块化时,我看到一些可能效率低下的表达式:
for( ; forCounter <= limit / number1 * number1; forCounter += number1)
for( ; forCounter <= limit / number2 * number2; forCounter += number2)
for( ; forCounter <= limit / (number1 * number2) * (number1 * number2); forCounter += number1 * number2)
这些计算只进行一次或每次迭代吗?一个接近的例子是循环中的表达式int x = 5
。第一次声明并初始化它,但在其他迭代中,它只是赋值。
答案 0 :(得分:2)
是的,这是非常低效的,因为这些计算是在每次迭代时完成的(如果在循环时间内limit
,number1
和number2
的视图不变,则某些时候编译器可以优化代码)。但是一般规则 - 需要在循环之前计算所有常量(在循环时间期间)表达式,但不是每次都在循环中计算。所以代码必须是这样的:
ULONG n = limit / number1 * number1;
for( ; forCounter <= n; forCounter += number1) { ...}
ULONG m = number1 * number2, n = limit / m * m;
for( ; forCounter <= n; forCounter += m) { ... }
修改强>
如果limit,number1和number2是常量值 例如
#define limit 999
#define number1 3
#define number2 5
limit / number1 * number1
也是常量表达式,在编译时计算。在这种情况下
for( ; forCounter <= limit / number1 * number1; forCounter += number1)
绝对正常有效。
但如果他们的变量是这样的:
ULONG limit, number1, number2;
每次迭代都可以重新评估 limit / number1 * number1
。这取决于编译器,优化和声明limit, number1, number2
的地方(在全局范围或函数中的本地) - 这些变量是否可以在循环时间内更改。这可能是优化自动但不保证。最好总是通过自我直接优化代码