简体   繁体   English

如果语句在循环内,反之亦然

[英]if statement inside a loop or vice versa

I'm wondering which is more efficient. 我想知道哪个更有效。

Let's say I have this code: 假设我有以下代码:

while (i<10000){
   if (cond1)
      doSomething1();
   else if (cond2)
      doSomething2();
   else
      doSomething3();
}

Now cond1 and cond2 are "constant" conditions, which means that if it happens once for i it will happen to all of them, and just one of them can be true. 现在, cond1cond2是“恒定”条件,这意味着,如果对i ,一旦发生一次,它将对所有它们都发生,并且其中只有一个是真实的。 Most of the time, the last doSomething3() is executed. 大多数情况下,将执行最后一个doSomething3()

Now what happens if I write something like this: 现在,如果我写这样的话会发生什么:

if (cond1){
   while (i<10000)
      doSomething1();
}
else if (cond2){
   while (i<10000)
      doSomething2();
}
else{
   while (i<10000)
      doSomething3();
}

Is it more efficient because I'm checking cond1 and cond2 just once? 因为我只检查一次cond1cond2,效率更高吗?

What you need to be asking is which is more cache-efficient. 您需要问的是哪种缓存效率更高。

In many cases, the compiler can figure this out for you and will rearrange your code to get the best results . 在许多情况下,编译器可以为您解决这个问题, 并将重新排列代码以获得最佳结果 Its ability to do so will depend largely on what doSomethingN does and what condN are. 它这样做的能力在很大程度上取决于doSomethingN功能和condN功能。 If condN can change over time, then it may well need to be physically checked each time, in which case your code cannot be substantially re-arranged and checking it on every loop iteration may indeed be far slower. 如果condN可以随时间变化,那么很可能每次都需要对其进行物理检查,在这种情况下,您的代码将无法进行实质性的重新安排,并且在每次循环迭代中对其进行检查的确可能会慢得多。 But, if condN is constant, the repeated checks can be optimised away, essentially resulting in your first code being converted into the second. 但是,如果condN不变,则可以优化重复检查,从而使您的第一个代码转换为第二个代码。

Ultimately, the only way to be sure is to measure it (and study the resulting assembly, if you can understand it). 最终,唯一可以确定的方法就是对其进行测量(如果可以理解,请研究最终的装配体)。

I think you've answered your own question. 我认为您已经回答了自己的问题。 Yes, it's more efficient if you write more efficient code. 是的,如果编写更高效的代码,它会更高效。

EDIT @NeilKirk has a point. 编辑 @NeilKirk有一点。 Since your compiler knows what it's doing, manually checking outside is only at least as efficient, not necessarily more efficient, if the compiler can detect that the condition won't change during your loop. 由于您的编译器知道它在做什么,因此,如果编译器可以检测到循环中条件不会改变,则手动进行外部检查至少同样有效,但不一定更高

On a first look, the second one looks like it is more efficient, after all one check is obviously more efficient than 10000 checks, well, more efficient performance wise, slightly more code is the price it comes at. 乍一看,第二个看起来效率更高,毕竟一个检查显然比10000个检查更有效,那么,在性能上更有效,代码价格更高。

But then again, the performance overhead of the first one may very well be negligible, you should really benchmark the two, because you know, you don't have a performance problem until you prove you do. 但是话又说回来,第一个的性能开销可能可以忽略不计,您应该对两者进行基准测试,因为您知道,在证明自己没有性能问题之前,就不会出现性能问题。

At any rate, any production grade compiler will likely be able to optimize things for you in that fairly static and easy to analyze context. 无论如何,任何生产级的编译器都可能会在相当静态且易于分析的上下文中为您优化事物。

It could be another scenario, where there are a lot more options, which might not be able to predict during compile time. 可能是另一种情况,那里有更多的选项,可能无法在编译期间进行预测。 For example you can have a hash map of conditions and function pointers, so you lookup the function pointer for the condition and use it to invoke the functionality. 例如,您可以具有条件和函数指针的哈希映射,因此您可以查找条件的函数指针并使用它来调用功能。 Naturally, this will be far less efficient, because it will use dynamic dispatch, which also means the calls cannot be inlined, but it is the price you pay for having it more flexible, for example using this approach you can register different functions and conditions during the runtime, you can change functionality for a given condition and whatnot. 自然,这将效率大大降低,因为它将使用动态分派,这也意味着无法内联调用,但这是您要使其更加灵活的代价,例如,使用此方法可以注册不同的功能和条件在运行时,您可以更改给定条件的功能,而不必更改。

For example consider a scenario where you need to perform 10000 actions, but each actions should depend on the result from the previous one. 例如,考虑一种情况,您需要执行10000个操作,但是每个操作应取决于前一个操作的结果。

while (i < 10000) cond = map[cond]();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM