标签:
这事情得从C语言开始说起,先编写下面这两段代码:
1、
#include<stdio.h> int main(void) { int i; for(i = 0; i < 10; i++) { } return 0; }
2、
#include<stdio.h> int main(void) { int i = 0; while (i < 10) { 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、
<?php for($i=0;$i<10;$i++) { echo 123; }
2、
<?php $i = 0; while ($i < 10) { 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给废除了。
标签:
原文地址:http://my.oschina.net/firebroo/blog/406286