良好实践:循环和如果声明

apn*_*ing 11 php c# ruby java language-agnostic

(我复制/粘贴我在Codereview上发布的相同问题:https://codereview.stackexchange.com/questions/1747/good-practice-loop-and-if-statement )

我想知道最佳做法是什么:

版本A:

loop1
  if condition1
    code1

  if condition2
    code2

  if condition3
    code3
Run Code Online (Sandbox Code Playgroud)

或者,版本B:

if condition1
  loop1 with code1

if condition2
  loop1 with code2

if condition3
  loop1 with code3
Run Code Online (Sandbox Code Playgroud)

我已经实现了版本B,因为它对我来说更具可读性,并且始终检查相同的条件似乎很荒谬.

但循环n次相同的阵列也可能被视为荒谬:)

saw*_*awa 7

从你正在考虑具有循环之外的条件的版本B的事实来看,我假设条件的真值不随阵列中的元素而变化.否则,你的问题就没有意义了.

结论

如果条件复杂使得它们相对于阵列的大小在评估中花费了很多时间,则版本B更快.如果是相反的方式,则版本A更快.

在这种情况下,哪个更快应该与您应采取的策略重合,因为在复杂结构中嵌入简单结构而不是在简单结构中嵌入复杂结构更容易理解.

说明

当条件相对于数组的大小足够简单时,迭代的成本超过评估条件的成本.如下面使用ruby所述,版本B较慢.

$a = (1..10000)

def versionA
  $a.each do
    nil if true
    nil if false
    nil if true
  end
end

def versionB
  $a.each {nil} if true
  $a.each {nil} if false
  $a.each {nil} if true
end

require 'benchmark'
n = 10000
Benchmark.bmbm do|b|
  b.report('A'){n.times{versionA}}
  b.report('B'){n.times{versionB}}
end

Rehearsal -------------------------------------
A   7.270000   0.010000   7.280000 (  7.277896)
B  13.510000   0.010000  13.520000 ( 13.515172)
--------------------------- total: 20.800000sec

        user     system      total        real
A   7.200000   0.020000   7.220000 (  7.219590)
B  13.580000   0.000000  13.580000 ( 13.605983)
Run Code Online (Sandbox Code Playgroud)

另一方面,如果相对于阵列上的迭代来评估条件成本更高,那么前者的效果将变得比后者更重要,并且速度将是另一种方式.

$a = (1..100)

def versionA
  $a.each do
    nil if (1..10).each{nil} && true
    nil if (1..10).each{nil} && false
    nil if (1..10).each{nil} && true
  end
end

def versionB
  $a.each {nil} if (1..10).each{nil} && true
  $a.each {nil} if (1..10).each{nil} && false
  $a.each {nil} if (1..10).each{nil} && true
end

require 'benchmark'
n = 10000
Benchmark.bmbm do|b|
  b.report('A'){n.times{versionA}}
  b.report('B'){n.times{versionB}}
end

Rehearsal -------------------------------------
A   2.860000   0.000000   2.860000 (  2.862344)
B   0.160000   0.000000   0.160000 (  0.169304)
---------------------------- total: 3.020000sec

        user     system      total        real
A   2.830000   0.000000   2.830000 (  2.826170)
B   0.170000   0.000000   0.170000 (  0.168738)
Run Code Online (Sandbox Code Playgroud)