Algorithm 嵌套的if与条件

Algorithm 嵌套的if与条件,algorithm,if-statement,optimization,Algorithm,If Statement,Optimization,在以下两者中,最有效的选择是什么: if(myConditionA){ if (myConditionB){ if (myConditionC){ //do something } } } 及 最佳选择是什么?为什么?这取决于语言吗 编辑:这不是一个关于代码质量的问题。如果您有这样的问题,最好的方法是避免使用这样的箭头代码: if (!myConditionA) return; if (!myConditionB)

在以下两者中,最有效的选择是什么:

if(myConditionA){
    if (myConditionB){
        if (myConditionC){
            //do something
        }
    }
}

最佳选择是什么?为什么?这取决于语言吗


编辑这不是一个关于代码质量的问题。

如果您有这样的问题,最好的方法是避免使用这样的箭头代码:

if (!myConditionA)
    return;
if (!myConditionB)
    return;
if (!myConditionC)
    return;
//do something
您还可以将所有条件放入另一个函数中,并像以下那样使用它:

if (!aggergateCondition())
    return;
// do something
它使您的代码干净易读,减少缩进量,使结构扁平化

编辑: 从理论上讲,更好的执行方式是带有
&&
语句的表单。为什么?因为它没有分支,而且很懒。if语句也有点懒惰,但它们是分支的

但这并不一定要成立。您必须考虑哪些语句可能会省略其中一些if语句,并且在
&&
运算符处可能会更频繁地中断(仅省略一个
if
语句要容易得多)。编译器还可能执行一些优化,这可能导致这两种
if
情况都会产生相同的程序集或字节码

因此,从根本上说,很难说哪一个性能更好,因为编译器优化甚至CPU架构的帷幕背后正在发生的魔力


如果您想要一些过早的优化教程,我推荐这本书给您:)

当您尝试它时发生了什么,为什么您会期望编译器产生的结果会有任何不同?您的算法在这两者之间没有区别

unsigned int one ( unsigned int myConditionA, unsigned int myConditionB, unsigned int myConditionC )
{
    if(myConditionA){
        if (myConditionB){
            if (myConditionC){
                //do something
                return(1);
            }
        }
    }
    return(0);
}
unsigned int two ( unsigned int myConditionA, unsigned int myConditionB, unsigned int myConditionC )
{
    if(myConditionA && myConditionB && myConditionC){
        //do something
        return(1);
    }
    return(0);
}

00000000 <one>:
   0:   e3510000    cmp r1, #0
   4:   13520000    cmpne   r2, #0
   8:   13a02001    movne   r2, #1
   c:   03a02000    moveq   r2, #0
  10:   e3500000    cmp r0, #0
  14:   03a00000    moveq   r0, #0
  18:   12020001    andne   r0, r2, #1
  1c:   e12fff1e    bx  lr

00000020 <two>:
  20:   e3510000    cmp r1, #0
  24:   13520000    cmpne   r2, #0
  28:   13a02001    movne   r2, #1
  2c:   03a02000    moveq   r2, #0
  30:   e3500000    cmp r0, #0
  34:   03a00000    moveq   r0, #0
  38:   12020001    andne   r0, r2, #1
  3c:   e12fff1e    bx  lr
unsigned int-one(unsigned int-myConditionA、unsigned int-myConditionB、unsigned int-myConditionC)
{
if(霉菌病){
if(myConditionB){
if(霉菌病){
//做点什么
申报表(1);
}
}
}
返回(0);
}
无符号int-two(无符号int-mycondition A、无符号int-mycondition B、无符号int-mycondition C)
{
if(myConditionA&&myConditionB&&myConditionC){
//做点什么
申报表(1);
}
返回(0);
}
00000000 :
0:e3510000 cmp r1,#0
4:13520000 cmpne r2,#0
8:13a02001电影r2#1
c:03a02000移动Q r2,#0
10:e3500000 cmp r0,#0
14:03a00000移动量r0,#0
18:12020001和NE r0,r2,#1
1c:E12FF1E bx lr
00000020 :
20:e3510000 cmp r1,#0
24:13520000 cmpne r2,#0
28:13a02001电影r2#1
2c:03a02000移动Q r2,#0
30:e3500000 cmp r0,#0
34:03a00000移动量r0,#0
38:12020001和NE r0,r2,#1
3c:E12FF1E bx lr
哈,好吧,这很难看,但这仅仅是因为我编写测试的方式,如果它们是一个或另一个,但不是两个,那么编译器会清楚地生成相同的代码。因此,如果您能够看到这一点,那么对其进行测量性能测试可能会显示出差异,但这是一个糟糕的测试

00000000 <two>:
   0:   10800006    beqz    $4,1c <two+0x1c>
   4:   00801025    move    $2,$4
   8:   10a00003    beqz    $5,18 <two+0x18>
   c:   00000000    nop
  10:   03e00008    jr  $31
  14:   0006102b    sltu    $2,$0,$6
  18:   00001025    move    $2,$0
  1c:   03e00008    jr  $31
  20:   00000000    nop

00000024 <one>:
  24:   08000000    j   0 <two>
  28:   00000000    nop
00000000:
0:10800006贝卡4,1c美元
4:00801025移动$2,$4
8:10a00003贝卡5,18美元
c:00000000无
10:03e00008 jr$31
14:0006102b sltu$2、$0、$6
18:00001025移动$2,$0
1c:03e00008 jr$31
20:00000000无
00000024 :
24:0800000J0
28:00000000无
另一个指令集

00000000 <_one>:
   0:   1d80 0002       mov 2(sp), r0
   4:   0308            beq 16 <_one+0x16>
   6:   0bf6 0004       tst 4(sp)
   a:   0306            beq 18 <_one+0x18>
   c:   15c0 0001       mov $1, r0
  10:   0bf6 0006       tst 6(sp)
  14:   0301            beq 18 <_one+0x18>
  16:   0087            rts pc
  18:   0a00            clr r0
  1a:   0087            rts pc

0000001c <_two>:
  1c:   1d80 0002       mov 2(sp), r0
  20:   0308            beq 32 <_two+0x16>
  22:   0bf6 0004       tst 4(sp)
  26:   0306            beq 34 <_two+0x18>
  28:   15c0 0001       mov $1, r0
  2c:   0bf6 0006       tst 6(sp)
  30:   0301            beq 34 <_two+0x18>
  32:   0087            rts pc
  34:   0a00            clr r0
  36:   0087            rts pc
00000000:
0:1d80 0002 mov 2(sp),r0
4:0308北京时间16时
6:0bf6 0004 tst 4(sp)
a:0306 beq 18
c:15C00001 mov$1,r0
10:0bf6 0006 tst 6(sp)
14:0301北京时间18时
16:0087 rts pc
18:0a00 clr r0
1a:0087 rts pc
0000001c:
1c:1d80 0002 mov 2(sp),r0
20:0308 beq 32
22:0bf6 0004 tst 4(sp)
26:0306 beq 34
28:15C00001 mov$1,r0
2c:0bf6 0006 tst 6(sp)
30:0301 beq 34
32:0087 rts pc
34:0a00 clr r0
36:0087 rts pc
不同的编译器

00000000 <one>:
   0:   e3510000    cmp r1, #0
   4:   13a01001    movne   r1, #1
   8:   e3500000    cmp r0, #0
   c:   13a00001    movne   r0, #1
  10:   e3520000    cmp r2, #0
  14:   e0000001    and r0, r0, r1
  18:   13a02001    movne   r2, #1
  1c:   e0000002    and r0, r0, r2
  20:   e12fff1e    bx  lr

00000024 <two>:
  24:   e3510000    cmp r1, #0
  28:   13a01001    movne   r1, #1
  2c:   e3500000    cmp r0, #0
  30:   13a00001    movne   r0, #1
  34:   e3520000    cmp r2, #0
  38:   e0000001    and r0, r0, r1
  3c:   13a02001    movne   r2, #1
  40:   e0000002    and r0, r0, r2
  44:   e12fff1e    bx  lr
00000000:
0:e3510000 cmp r1,#0
4:13a01001移动r1,#1
8:e3500000 cmp r0,#0
c:13a00001移动r0,#1
10:e3520000 cmp r2,#0
14:e0000001和r0、r0、r1
18:13a02001电影r2#1
1c:e0000002和r0、r0、r2
20:E12FF1E bx lr
00000024 :
24:e3510000 cmp r1,#0
28:13a01001移动r1,#1
2c:e3500000 cmp r0,#0
30:13a00001移动r0,#1
34:e3520000 cmp r2,#0
38:e0000001和r0、r0、r1
3c:13a02001移动r2,#1
40:e0000002和r0、r0、r2
44:E12FF1E bx lr
另一个编译器的另一个目标

00000000 <one>:
   0:   27bdfff8    addiu   $29,$29,-8
   4:   afbe0004    sw  $30,4($29)
   8:   03a0f025    move    $30,$29
   c:   0005082b    sltu    $1,$0,$5
  10:   0004102b    sltu    $2,$0,$4
  14:   00410824    and $1,$2,$1
  18:   0006102b    sltu    $2,$0,$6
  1c:   00221024    and $2,$1,$2
  20:   03c0e825    move    $29,$30
  24:   8fbe0004    lw  $30,4($29)
  28:   03e00008    jr  $31
  2c:   27bd0008    addiu   $29,$29,8

00000030 <two>:
  30:   27bdfff8    addiu   $29,$29,-8
  34:   afbe0004    sw  $30,4($29)
  38:   03a0f025    move    $30,$29
  3c:   0005082b    sltu    $1,$0,$5
  40:   0004102b    sltu    $2,$0,$4
  44:   00410824    and $1,$2,$1
  48:   0006102b    sltu    $2,$0,$6
  4c:   00221024    and $2,$1,$2
  50:   03c0e825    move    $29,$30
  54:   8fbe0004    lw  $30,4($29)
  58:   03e00008    jr  $31
  5c:   27bd0008    addiu   $29,$29,8
00000000:
0:27bdfff8加上$29,$29,-8
4:afbe0004 sw$30,4($29)
8:03a0f025移动$30,$29
c:0005082b sltu$1、$0、$5
10:0004102b sltu$2、$0、$4
14:00410824和$1、$2、$1
18:0006102b sltu$2、$0、$6
1c:00221024和$2、$1、$2
20:03c0e825移动$29,$30
24:8fbe0004 lw$30,4($29)
28:03e00008 jr$31
2c:27bd0008加上$29,$29,8
00000030 :
30:27bdfff8加上$29,$29,-8
34:afbe0004 sw$30,4($29)
38:03a0f025移动$30,$29
3c:0005082b sltu$1、$0、$5
40:0004102b sltu$2、$0、$4
44:00410824和$1、$2、$1
48:0006102b sltu$2、$0、$6
4c:00221024和$2,$1,$2
50:03c0e825移动$29,$30
54:8fbe0004 lw$30,4($29)
58:03e00008 jr$31
5c:27bd0008加上$29,$29,8

即使没有优化,我也得到了同样的结果。这两者之间没有区别,那么为什么编译器会产生可能是性能差异的差异呢?

短路
&&
和嵌套之间几乎没有区别
00000000 <one>:
   0:   27bdfff8    addiu   $29,$29,-8
   4:   afbe0004    sw  $30,4($29)
   8:   03a0f025    move    $30,$29
   c:   0005082b    sltu    $1,$0,$5
  10:   0004102b    sltu    $2,$0,$4
  14:   00410824    and $1,$2,$1
  18:   0006102b    sltu    $2,$0,$6
  1c:   00221024    and $2,$1,$2
  20:   03c0e825    move    $29,$30
  24:   8fbe0004    lw  $30,4($29)
  28:   03e00008    jr  $31
  2c:   27bd0008    addiu   $29,$29,8

00000030 <two>:
  30:   27bdfff8    addiu   $29,$29,-8
  34:   afbe0004    sw  $30,4($29)
  38:   03a0f025    move    $30,$29
  3c:   0005082b    sltu    $1,$0,$5
  40:   0004102b    sltu    $2,$0,$4
  44:   00410824    and $1,$2,$1
  48:   0006102b    sltu    $2,$0,$6
  4c:   00221024    and $2,$1,$2
  50:   03c0e825    move    $29,$30
  54:   8fbe0004    lw  $30,4($29)
  58:   03e00008    jr  $31
  5c:   27bd0008    addiu   $29,$29,8