这事情得从C语言开始说起,先编写下面这两段代码:
1、
#include
int main(void) {
int i;
for(i = 0; i
}
return 0;
}
2、
#include
int main(void) {
int i = 0;
while (i
i++;
}
return 0;
}
然后我们用GCC分别生成上面两段代码的汇编代码,我的GCC版本是gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
使用的命令gcc 1.c -std=c99 -S -o 1.s -masm=intel -O2
这里我使用O2优化,汇编风格是intel风格。
1、
我们diff一下这两个汇编文件:
经过优化之后for和while生成的指令一模一样,没有区别,所以在C语言中while就是for的语法糖而已。
上面验证的结论难道适用于所有语言吗?当然不是。
我们看看PHP的for和while。鸟哥在blog里面说过zend引擎不会对php做任何语义上的优化。
我们来验证下,编写如下两段测试代码:
1、
for($i=0;$i<10;$i++) {
echo 123;
}
2、
$i = 0;
while ($i
echo 123;
$i++;
}
然后使用vld扩展看看生成的opcode是不是一样的。
1、
分析下for的opcode,上面的代码逻辑大概是这样的,!0是一个compile_var,和10进行比较,如果!0比10大,JMP到11行退出程序,如果!0比10小,则JMP到第八行,开始执行循坏体里面的内容,执行到第10行JMP到第五行,执行$i++,这个操作对应这两条指令POST_INC和FREE。执行完之后JMP到第二行。
2、
分析下while循环的opcode,看第三行,和for一样,比较!0和10的大小,这里使用的跳转指令是JMPZ,如果等于0就跳转到第九行,也就是!0比10大或则等于的时候,如果小于的话开始执行循环体里面的内容,然后执行$i++,执行到第10行的时候JMP到第三行。
从分析上来看while比for花费了更少的指令,而且个人感觉JMPZ指令应该是比JMPZNZ简单的多的指令,所以在PHP里面while是比for要快的。
PHP的opcode对照表可以在这里查看
这样子看起来出一个优秀的PHP程序员比出一个优秀的C程序员要难,因为只能靠程序员自己手动优化来使用代码达到最高的效率,鉴于此,我在想PHP是不是可以把for给废除了。