考虑以下两种情况:
boolean b = false;
int i = 0;
while(i++ < 5) {
b = true;
}
OR
boolean b = false;
int i = 0;
while(i++ < 5) {
if(!b) {
b = true;
}
}
哪个更“昂贵”?如果答案取决于使用的语言/编译器,请提供。我的主要编程语言是Java。
请不要问我为什么要这样做的问题......他们只是指出相关的准系统示例:如果变量在循环中反复设置相同的值,或者应该进行测试在它拥有需要改变的值的每个循环上?
答案 0 :(得分:29)
请不要忘记rules of Optimization Club。
您似乎违反了规则2.您没有测量。如果您真的想知道,您将通过设置针对方案B运行方案A并找到答案的测试来自己回答问题。不同环境之间存在很多差异,我们无法回答。
答案 1 :(得分:3)
你测试过这个吗?在Linux系统上工作时,我将第一个示例放在一个名为LoopTestNoIf.java的文件中,将第二个示例放在一个名为LoopTestWithIf.java的文件中,包含一个主函数和类,围绕每个文件编译,然后使用这个bash脚本运行:
#!/bin/bash
function run_test {
iter=0
while [ $iter -lt 100 ]
do
java $1
let iter=iter+1
done
}
time run_test LoopTestNoIf
time run_test LoopTestWithIf
结果是:
real 0m10.358s
user 0m4.349s
sys 0m1.159s
real 0m10.339s
user 0m4.299s
sys 0m1.178s
显示if使得我的系统上的速度稍快一些。
答案 2 :(得分:1)
你是否试图找出执行分配的每个循环在总运行时间上是否比检查每个循环更快并且仅在满足测试条件时分配一次?
在上面的例子中,我猜第一个更快。您执行5个作业。在后者中,您执行5次测试,然后执行任务。
但你需要提高迭代次数并投入一些秒表计时器才能确定。
答案 3 :(得分:0)
任何编译器(可能在调试中除外)都会将这两个语句优化为
bool b = true;
但通常,赋值和分支的相对速度取决于处理器体系结构,而不依赖于编译器。一个现代的超标量处理器在分支上表现可怕。一个简单的微控制器每个指令使用大致相同的周期数。
答案 4 :(得分:0)
相对于你的准系统示例(也许是你真正的应用程序):
boolean b = false;
// .. other stuff, might change b
int i = 0;
// .. other stuff, might change i
b |= i < 5;
while(i++ < 5) {
// .. stuff with i, possibly stuff with b, but no assignment to b
}
问题解决了吗?
但实际上 - 这将是一个关于测试成本(通常不只是if (boolean)
)和作业成本(通常不仅仅是primitive = x
)的问题。如果测试/分配很昂贵或者你的循环足够长或者你有足够高的性能要求,你可能想把它分成两部分 - 但所有这些标准都要求你测试事情的执行方式。当然,如果您的要求更高(例如,b
可以来回翻转),您可能需要更复杂的解决方案。
答案 5 :(得分:0)
实际上,这是我感兴趣的问题……(我希望我能在某个地方找到答案以避免自己的测试。嗯,我没有……)
为确保您的(mine)测试有效,您(I)必须进行足够的迭代才能获取足够的数据。每次迭代都必须足够长(我是指时间尺度)以显示出真正的差异。我发现,即使十亿次迭代也不足以适应足够长的时间间隔,所以我写了这个测试:
for (int k = 0; k < 1000; ++k)
{
{
long stopwatch = System.nanoTime();
boolean b = false;
int i = 0, j = 0;
while (i++ < 1000000)
while (j++ < 1000000)
{
int a = i * j; // to slow down a bit
b = true;
a /= 2; // to slow down a bit more
}
long time = System.nanoTime() - stopwatch;
System.out.println("\\tasgn\t" + time);
}
{
long stopwatch = System.nanoTime();
boolean b = false;
int i = 0, j = 0;
while (i++ < 1000000)
while (j++ < 1000000)
{
int a = i * j; // the same thing as above
if (!b)
{
b = true;
}
a /= 2;
}
long time = System.nanoTime() - stopwatch;
System.out.println("\\tif\t" + time);
}
}
我进行了三次将数据存储到Excel中的测试,然后交换了第一个('asgn')和第二个('if')案例,然后再次运行了三次……结果如何? “ if”案四次“胜诉”,“ asgn”案两次“胜诉”似乎更好。这显示了执行可能有多敏感。但总的来说,我希望这也证明了“如果”的情况是更好的选择。
无论如何,谢谢……