Was passiert, wenn man es versucht, und warum sollten Sie es erwarten, mit keinen Unterschied überhaupt zu sein, was der Compiler erzeugt? Es gibt keinen Unterschied in Ihrem Algorithmus zwischen den beiden.
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
hah, okay das war hässlich, aber nur, weil, wie ich schrieb den Test, hatte diese schon das eine oder andere, aber nicht beides dann würde der Compiler den gleichen Code eindeutig hervorgebracht hat. Ein gemessener Leistungstest könnte also einen Unterschied zeigen, wenn Sie das sehen könnten, aber es ist ein schlechter Test.
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
ein weiterer Befehlssatz.
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
verschiedene Compiler
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
ein anderes Ziel mit dem anderen Compiler
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
Auch unoptimized bekam ich das gleiche Ergebnis. Es gibt keinen Unterschied zwischen den beiden, warum sollte der Compiler eine Differenz erzeugen, die einen Leistungsunterschied darstellt?
Hängt, wenn Sie sonst Bedingungen haben –
nur grundlegende wenn, sonst keine Aussagen für diesen Fall – d3cima
Es hängt auch von der Sprache ab. Die meisten, aber nicht alle Sprachen haben eine Kurzbewertung. Wenn dies nicht der Fall ist, ist die erste Version effizienter, da Sie die Short-Cut-Bewertung tatsächlich implementieren. Beachten Sie, dass, wenn die Bedingungen Nebenwirkungen haben und keine kurze Bewertung vorhanden ist, ein Unterschied im Verhalten zwischen den beiden bestehen kann. – trincot