在PHP 5.4的更新list上, 有一句: 提升了Zend引擎的性能, 减少了内存占用.
那么, 到底是怎么提升的呢?避免不必要的Hashtable我们知道在PHP中, 类的属性/静态属性/常量, 都是保存在Hashtable中的, 而在以前, 即使一个类没有申明属性/静态属性/常量, Zend引擎也会为他们分配Hashtable.
而在现在, 这个过程被优化了, 只有在有元素的时候才会分配Hashtable.
这样就避免一些emalloc/efree操作, 减少一些内存占用.
四元式优化在PHP中, 真正执行的是Opcodes, 一个Opcodes包含3个固定的操作数, result, left, right, 在以前, 这三个操作数每一个都包含一个zval, 即使根本用不到的时候, 比如没有右操作数的时候, 还会为右操作数分配一个zval.
而在现在, 所有的操作数将不再直接包含zval, 而是包含一个literal table的指针, 每一个op array都会包含一个literal table.
并且znode也做了相应的调整.
这样一来, 也能减少一些内存占用. 从之前的(32位操作系统)一个opcode占用72byte, 到现在的28byte.
另外, 对于string, literal table还会保存一份这个string的预先计算的hash值, 避免了在运行时多次计算. 从而提高一部分性能.
字面字符串就好像C语言中, 代码中的字面字符串, 会保存在一个固定段内(数据段), 在整个执行时期, 这些字符串都是常量字符串,不能被修改,不能被free.
PHP也借鉴了这样的思想, 提出一个Internal string的概念, 在PHP代码中的字面量字符串, 将会一次分配, 并前在整个执行期都不能被修改.
PHP在copy_zval, free zval等操作的时候, 会对internal string特别处理, 避免不必要的free和复制.
并且这些字面量字符串的hash值将会被预先计算, 这样一来, 对于字符串比较 ==, 以及hashtable中的hash计算来说, 都可以直接使用这个预先计算的hash值, 从而能提高一部分性能.
其他当然, 还有很多优化点, 比如优化了opcode, 减少了一些不必要的opcodes, 在此就不一一赘述了.
对比下面是PHP开发小组内部测试的一些数据:php-trunkpatchedinprovementbench.php (sec)4.313.4919%micro_bench.php (sec)19.7814.6326%一些实际的应用:php-trunkpathcedimprovementblog (req/sec)59.366.212%drupal (req/sec)1073.91084.81%fw (req/sec)105.3111.86%hello (req/sec)5362.55351.40%qdig (req/sec)243.4253.74%typo3 (req/sec)355.3382.68%wordpress (req/sec)101.8108.57%xoops (req/sec)70.378.512%scrum (req/sec)86.5104.220%从这些数据来看, 性能提升还是很明显的..
