2017-07-25 49 views
3

所以,让我们考虑有以下摘录的情况:在迭代中放置条件语句是不好的做法吗?

if(x = 0) 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something 
    } 
} 
else 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something different 
    } 
} 

正如你可以看到,这两个条件通过相同的循环重复进行,但根据条件不同的动作。我的问题是,它是一个不好的做法是这样的:

for(var i =0; i < 5; ++ i) 
{ 
    if(x = 0){ 
     // do something 
    }else{ 
     // do something else 
    } 
} 

原因是,我认为这可能是一个不好的做法是由于这样的事实,对于循环的每个实例,条件检查正在对其执行,首先检查条件,然后执行循环。我错了吗?

+2

Nitpick:请注意条件表达式中的“x = 0”赋值。 – doynax

+0

@doynax我提交了一个编辑,但由于某种原因它被拒绝了。 – hnefatl

+0

@hnefatl可能是因为这会改变OP代码的行为。我们都知道这可能是一个错字,但它是由OP来决定的...... –

回答

4

除非你正在编写的代码,必须高速运行,并超高效,去代码的可读性超过效率。在这种情况下,我会说第二个例子更清晰,因为它的代码更少,并且通常遵循一种模式。

我猜想,虽然考虑的另一个因素是,第二个例子似乎暗示x可能会改变值,而第一个例子没有。这是值得在解释选择附近发表评论。

我的直觉会同意你的观点,第一个例子会更有效率,但实际上编译器的优化很可能会使上面的例子变得很短 - 它们在性能上可能是相同的。

下面是可以在循环中进行优化的pretty impressive list,给出一个想法,并且branch optimisation(请参阅答案)可能会在循环运行多次迭代时产生影响。

+0

如果你给出了其他例子,比如长循环或循环中的循环,那会更好。这些案例的结果会非常不同。 – ReadyFreddy

+1

@ReadyFreddy我不太了解编译器优化以提供很好的示例 - 我将添加一些链接到似乎相关的资源,尽管这很重要。如果您可以添加示例,请随时编辑我的答案。 – hnefatl

+0

@hnefatl:的确如此。第一种变体通常在优化速度时更为可取,第二种变体则优化尺寸。注意,如果在关键代码路径上使用依赖于优化器的自动托管是脆弱的,因为在一般情况下证明'x'是否可能通过别名改变或类似改变是不平常的。本地副本可能是一个有帮助的提示,但是当然它会反过来让程序员证明'x'是恒定的。 – doynax

0

如果使用

if(x = 0) 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something 
    } 
} 
else 
{ 
    for(var i = 0; i < 5; ++ i) 
    { 
     //do something different 
    } 
} 

那么你已经做了一个比较,并在范围内执行任务的5次的循环。

当您使用

for(var i =0; i < 5; ++ i) 
{ 
    if(x = 0){ 
     // do something 
    }else{ 
     // do something else 
    } 
} 

然后在范围执行任务5次的循环。除此之外,比较完成5次。

乍一看前者导致指令最少。但编译器/解释器可以通过一次比较来执行优化步骤。但这取决于编译器/解释器。如果您对编译器/解释器如何针对您正在编程的给定语言有很好的理解,则可以“滥用”该知识来编写可读代码,并且具有良好优化的输出。

然而,另一种选择是使用函数工作。这种方法是如果变量x是恒定整个循环,与其它词时才有用:你在循环过程本身不会修改它。第一个例子就是这种情况。然而,在第二个例子中:x可以在循环,这导致在循环期间运行的是if {}else{}块,执行两种不同的功能改变。

备选:第一选择一个功能,并在循环使用它。如果你有很多不同的任务要执行,它可能会更有用。事先选择一个功能。有些编程语言允许这样做,另一种不允许。所以这取决于语言本身。

// check which function to run 
variable runThisFunction; 
if (x = 0) runThisFunction = { // do something } 
else runThisFunction = { // do something else } 

// loop 5 times using the function 
for(var i =0; i < 5; ++ i) 
{ 
    call runThisFunction with arg i provided. 
} 
+0

值得注意的是,如果有机会“做某件事”或“做其他事情”来改变'x'的值,那么这些并不等同。 –

+0

(这总是假设OP真的意味着'x == 0'而不是'x = 0') –

+1

@JordiNebot是真的,但是如果你看第一个例子,你可以看到他试图选择一个任务,然后做它5次。 Ofc在第二个例子中可能会有所不同,可以修改'x'。如果它改变了,那么我的例子是无效的。 Gotcha编辑帖子 – KarelG

相关问题