在Zend引擎和擴展中,常常要建立一個PHP的變量,底層就是一個zval指針。以前的版本都是經過MAKE_STD_ZVAL動態的從堆上分配一個zval內存。而PHP7能夠直接使用棧內存。PHP代碼中建立的變量也進行了優化,PHP7直接在棧內存上預分配zval。這樣節約了大量內存分配和內存管理的操做。算法
PHP5性能優化
zval *val; MAKE_STD_ZVAL(val);
PHP7數據結構
zval val;
PHP7爲字符串單首創建了新類型叫作zend_string,除了char *指針和長度以外,增長了一個hash字段,用於保存字符串的hash值。PHP中array是核心數據結構,PHP程序中每每都有大量的$array[$key]操做,雖然hashtable查找的時間複雜度是O(1),但$key要轉爲hash值是要通過計算的。不只僅是array操做,實際上PHP底層對於類屬性、類方法、函數,訪問時都要先經過hashtable查找到對應的指針,再執行對應的操做。PHP7以前Zend引擎會有大量的CPU時間用於計算hash值。函數
實際上PHP程序運行起來以後,大部分狀況下$key的值都是不變的。PHP7乾脆將這個hash值保存起來,下次直接使用,這樣就節省了大量的hash計算操做,PHP的hashtable與C數性能
組的性能一致。優化
從實際項目進行callgrind性能分析,會發現alloc和hash 2項操做就佔用了至關大比例的CPU時間。PHP7優化以後這2項操做佔用的CPU時間下降了很是多。(注:zend_hash仍然佔12%,由於總體CPU下降了,因此總的耗時下降了很多)this
PHP5的hashtable每一個元素都是一個 Bucket *,而PHP7直接存Bucket,減小了內存申請次數,提高了Cache命中率和內存訪問速度。spa
PHP的C擴展函數與PHP中的變量進行參數輸入時,要使用zend_parse_parameters()函數,這個函數根據一個字符串參數找到對應PHP的zval指針,而後進行賦值。 這個函數實際上有必定的性能消耗。PHP7直接使用宏替換了zend_parse_parameters函數,C擴展中再也不須要使用zend_parse_parameters進行逐個參數的查找,宏展開後自動會實現參數賦值。僅此一項就提高了5%的性能。指針
不少PHP程序中會大量使用call_user_function, is_int/string/array, strlen , defined 函數。PHP5 都是以擴展函數的方式提供,PHP7中這4類函數改爲ZendVM的OPCODE指令,執行更快。code
除了上面5個主要優化點以外,PHP7還有其餘更多的細節性能優化。如基礎類型int、float、bool等改成直接進行值拷貝,排序算法改進,PCRE with JIT,execute_data和opline使用全局寄存器等等。PHP7對性能的優化會繼續進行下去。
PHP7-alpha相比PHP5.6性能提高了近3倍。下面是WordPress在PHP7上的表現:
除了性能優化外,PHP7新增長了2項重要的新特性。
PHP7版本函數的參數和返回值增長了類型限定。爲何PHP要加入類型,實際上此項特性是爲了PHP7.1版本的JIT特性作準備,增長類型後PHP JIT能夠準確判斷變量類型,生成最佳的機器指令。
function test(int $a, string $b, array $c) : int { //code }
PHP程序出錯後過去Zend引擎會發生致命錯誤並終止程序運行,PHP7可使用try/catch捕獲錯誤。底層使用Exeception代替了Fatal Error。這個特性表示PHP語言正在向一個更加規範的方向發展。應用層與底層在錯誤拋出的方式所有統一爲異常。
try { non_exists_func(); } catch (EngineException $e) { echo "Exception: {$e->getMessage()}\n"; }
$test = new class("Hello World") { public function __construct($greeting) { $this->greeting = $greeting; } };
最初PHP7性能優化的方向並非以上所講的,而是JIT。JIT是just in time的縮寫,表示運行時將指令轉爲二進制機器碼。Java語言的JVM引擎底層就是使用JIT將Java字節碼編譯爲二進制機器碼執行。PHP7開發過程當中有一箇中間版本是基於JIT,後來開發組發現使用JIT後,對於實際項目並無有太大的性能提高,因此PHP7最終放棄了JIT方案,PHP7.0-final版本不會攜帶JIT特性。
但若是是密集計算類程序就不一樣了,使用JIT將PHP OpCode編譯爲機器碼,運算的性能會大幅提高。PHP官方開發組在2014年末重啓了JIT的開發工做。