为什么代码:
for( i = 0, j = 0; i < 4 , j < 3; i++, j++)
比慢
for( i = 0, j = 0; i < 4 && j < 3; i++, j++)
详细阐述了一些用户提出的两个if语句比一个带有&;操作员:我在没有for循环的情况下测试了它,但它不是真的。两个if语句比一个带&;操作人员
第一个代码并不慢;至少在CCD_ 1中没有优化。事实上,它应该更快。
当你编译并反汇编这两个代码时,你会发现第一个代码是这样的:
cmpl $0x2,-0x8(%rbp)
jle 26 <main+0x26>
这是第二个:
cmpl $0x3,-0x4(%rbp)
jg 44 <main+0x44>
cmpl $0x2,-0x8(%rbp)
jle 26 <main+0x26>
在第一个例子中,gcc
只评估第二部分,因为第一部分没有效果,也没有在比较中使用。在第二个中,它必须检查第一个,然后,如果为true,则检查第二个。
因此,在一般情况下,第一个例子应该比第一个更快。如果你发现第一个速度较慢,也许你的测量方法不是100%正确的。
它们的执行时间可能没有变化,但迭代次数可能很大,因为:
如果我们将逗号分隔条件放入for循环中,它将计算最后一个条件的值。所以基本上,无论你先写哪个条件,它都会被忽略,第二个条件会被检查。因此j = 0; i < 4
将始终检查i<4
,其中i < 4 && j < 3
将检查并返回true,当且仅当两个条件都是true
。
参考
如果我们检查您所拥有的代码的汇编,您可能会看到的差异
程序
int main()
{
int x,y;
for(x=0,y=0;x<4,y<5;x++,y++);
printf("New one");
for(x=0,y=0;x<4 && y<5;x++,y++);
}
获取程序集的命令:gcc -S <program name>
装配
.file "for1.c"
.section .rodata
.LC0:
.string "New one"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl $0, 24(%esp)
movl $0, 28(%esp)
jmp .L2
.L3:
addl $1, 24(%esp)
addl $1, 28(%esp)
.L2:
cmpl $4, 28(%esp) //Here only one condition
jle .L3
movl $.LC0, (%esp)
call printf
movl $0, 24(%esp)
movl $0, 28(%esp)
jmp .L4
.L6:
addl $1, 24(%esp)
addl $1, 28(%esp)
.L4:
cmpl $3, 24(%esp) //First Condition
jg .L7
cmpl $4, 28(%esp) //Second Condition
jle .L6
.L7:
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits
所以,很明显,如果我们有2种情况,那么这将需要更多的时间。
第一个选项一是两个if,第二种选择是一个数学方程和一个通常更快的if,在这里,如果通过计算节省了处理时间,则可以保存一个。
第一个选项->if()&;if(),
第二个选项->if(()&;())