PHP7作了哪些優化

一  zval使用棧內存

在Zend引擎和擴展中,常常要建立一個PHP的變量,底層就是一個zval指針。以前的版本都是經過MAKE_STD_ZVAL動態的從堆上分配一個zval內存。而PHP7能夠直接使用棧內存。PHP代碼中建立的變量也進行了優化,PHP7直接在棧內存上預分配zval。這樣節約了大量內存分配和內存管理的操做。算法

PHP5性能優化

zval *val; MAKE_STD_ZVAL(val);

 

PHP7數據結構

zval val;

二 zend_string存儲hash值,array查詢再也不須要重複計算hash

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

 

 

三 hashtable桶內直接存數據

PHP5的hashtable每一個元素都是一個 Bucket *,而PHP7直接存Bucket,減小了內存申請次數,提高了Cache命中率和內存訪問速度。spa

四 zend_parse_parameters改成宏實現

PHP的C擴展函數與PHP中的變量進行參數輸入時,要使用zend_parse_parameters()函數,這個函數根據一個字符串參數找到對應PHP的zval指針,而後進行賦值。 這個函數實際上有必定的性能消耗。PHP7直接使用宏替換了zend_parse_parameters函數,C擴展中再也不須要使用zend_parse_parameters進行逐個參數的查找,宏展開後自動會實現參數賦值。僅此一項就提高了5%的性能。指針

五 新增長4種OPCODE

不少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的新特性

除了性能優化外,PHP7新增長了2項重要的新特性。

1. 變量類型

PHP7版本函數的參數和返回值增長了類型限定。爲何PHP要加入類型,實際上此項特性是爲了PHP7.1版本的JIT特性作準備,增長類型後PHP JIT能夠準確判斷變量類型,生成最佳的機器指令。

function test(int $a, string $b, array $c) : int {
  //code
}

2. 錯誤異常

PHP程序出錯後過去Zend引擎會發生致命錯誤並終止程序運行,PHP7可使用try/catch捕獲錯誤。底層使用Exeception代替了Fatal Error。這個特性表示PHP語言正在向一個更加規範的方向發展。應用層與底層在錯誤拋出的方式所有統一爲異常。

try {
  non_exists_func();
} catch (EngineException $e) {
  echo "Exception: {$e->getMessage()}\n";
}

3. 匿名類

$test = new class("Hello World") {
  public function __construct($greeting) {
      $this->greeting = $greeting;
  }
};

PHP7與JIT

最初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的開發工做。

相關文章
相關標籤/搜索