算法是程序的灵魂,优化算法有很多,关键是针对不同的问题运用合适的算法解决,以下是算法和代码优化的例子。

一、如何写出最快的循环

optimization_1
optimization_2

对比第一种方法和第二种方法,因为在PHP中,最终被执行的是OPCODE(php程序执行的最基本单位),每行都有俩个操作数,对于操作数来说,一般有3种类型的存取方式:临时变量、变量、和编译时变量、这三种变量其中,存取最快的是第三种,编译器变量,在OpCode执行过程中,会讲一个变量的加一级引用存储在一个hash结构中,用来加快存取速度。
在第一种方法中:

optimization_3

因为对于++$i来说,我们需要得到它的返回值,来和20000做比较,这样就会使得PHP在编译的时候,生成一个变量(IS_VAR),来保存自增的结果,也就是说,这个时候用到了oplinereturn操作数;然后,PHP会拿这个变量(IS_VAR)来和20000做比较。
而对于第二种方式:

optimization_4

这个过程中,$i已经优化成了编译变量(IS_CV),而对于++$i,因为我们不需要保存他的返回值,所以也只是直接对编译变量进行自增。
也就是说,方法一和方法二的速度差异,就在于对于方式二,我们一直都在实用编译变量,编译变量的存取速度远快于变量(IS_VAR)。
再来看第三种和第四种方式:

optimization_5

我们知道后缀自增(POST_INC),会返回一个对原值的copy,然后自增;对于第四种方式,$i++以后,ZE会将$i的原值,存储在一个临时变量(IS_TMP_VAR);并且会拿这个临时变量和20000对比。所以,严格来讲,这部分的速度比起第一种方式来说是会慢一些的。
而第三种方式慢在,因为对$i++的返回值没有使用,在语法分析阶段,$j++会归约成(rw_variable T_INC->expr_without_variable->expr, expr+’;’ => zend_do_free);所以ZE就会安排一条opline,free掉这个临时变量。

二、三元式与if-else比较

optimization_6
编译器的角度讲,二元运算速度比三元运算速度稍微快一点点,但是这个差距是完全可以忽略的;三元运算对代码可读性的提升是非常明显的。

三、for和foreach比较

optimization_7
循环数字数组时,for需要事先count($arr)计算数组长度,需要引入自增变量$i,每次循环都要进行条件判断$i<$c,然后自增$i++,输出数组元素时,$row[$i]需要进行哈希操作。
而foreach循环数组时,指针会自动指向下一个元素,不需要计算数组长度,没有条件判断和自增变量,调用元素时也没有哈希操作,所以性能肯定要比for高;所以,遍历数组,首选foreach。

四、$_SERVER[‘REQUEST_TIME’]和time()

optimization_8
获取Unix时间戳时用$_SERVER[‘REQUEST_TIME’] 代替time(); wamp环境测试性能提示20~30%/Linux生产环境测试性能提升 500% (5倍)。

五、判断字符串长度

optimization_9
strlen()函数函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化、哈希查找,会跟随被调用的函数一起执行。因此在某些情况下,合理使用isset()可以加速你的程序。因为isset()是一种语言结构,它的执行不需要函数查找和字母小写化等。

最后更新: 2017年11月19日 20:17

原始链接: http://blog.minhow.com/2016/10/14/php/code-algorithm/

× 请我吃糖~
打赏二维码