我想知道哪个更有效率。
假设我有这段代码:
while (i<10000){
if (cond1)
doSomething1();
else if (cond2)
doSomething2();
else
doSomething3();
}
现在 cond1 和 cond2 是“常量”条件,这意味着如果它i
发生一次,它将发生在所有这些条件上,并且只是其中一个可以是真的。
大多数情况下,执行最后一次doSomething3()
。
如果我写下这样的话,会发生什么:
if (cond1){
while (i<10000)
doSomething1();
}
else if (cond2){
while (i<10000)
doSomething2();
}
else{
while (i<10000)
doSomething3();
}
它是否更高效,因为我只检查 cond1 和 cond2 一次?
答案 0 :(得分:3)
您需要问的是哪种缓存效率更高。
在许多情况下,编译器可以为您和will rearrange your code to get the best results计算出来。它这样做的能力在很大程度上取决于doSomethingN
做什么和condN
是什么。如果condN
可能随时间发生变化,那么每次都可能需要对其进行物理检查,在这种情况下,您的代码无法进行实质性重新排列,并且在每次循环迭代时检查它可能确实要慢得多。但是,如果condN
是常量,则可以优化重复检查,从而导致第一个代码转换为第二个代码。
最终,唯一可以确定的方法是测量它(如果你能理解的话,研究生成的装配体)。
答案 1 :(得分:0)
我想你已回答了自己的问题。是的,如果你编写更有效的代码,它会更有效率。
编辑 @NeilKirk有一个观点。由于您的编译器知道它正在做什么,如果编译器可以检测到,那么在外部手动检查只有至少有效,而不一定更多有效在你的循环中,条件不会改变。
答案 2 :(得分:0)
初看起来,第二个看起来效率更高,毕竟一次检查显然比10000次检查效率更高,而且性能更高效,代码就是价格略高一些。
但话说回来,第一个的性能开销几乎可以忽略不计,你应该对两者进行基准测试,因为你知道,在你证明这一点之前,你没有性能问题。
无论如何,任何生产级编译器都可能能够在相当静态且易于分析的环境中为您优化。
这可能是另一种情况,其中有更多选项,可能无法在编译期间预测。例如,您可以拥有条件和函数指针的哈希映射,因此您可以查找条件的函数指针并使用它来调用该函数。当然,这样效率会低得多,因为它会使用动态调度,这也意味着调用不能内联,但这是为了让它更灵活所付出的代价,例如使用这种方法可以注册不同的功能和条件在运行时,您可以更改给定条件的功能等等。
例如,考虑一个需要执行10000个操作的场景,但每个操作都应该取决于前一个操作的结果。
while (i < 10000) cond = map[cond]();