摘要:但在密集計算方面比等靜態編譯語言差幾十倍甚至上百倍。一使用棧內存在引擎和擴展中,經常要創建一個的變量,底層就是一個指針。代碼中創建的變量也進行了優化,直接在棧內存上預分配。應用層與底層在錯誤拋出的方式全部統一為異常。
原文:http://rango.swoole.com/archives/440
最近PHP官方終于發布了傳說中的PHP7,雖然只是alpha版。PHP7號稱是新一代的PHP,官方開發組對Zend引擎底層做了大量修改來優化PHP的性能。可以說PHP7這個版本的主題就是性能優化。
在過去PHP一直以開發效率快著稱,而語言本身的性能較差(當然比Python,Ruby還是要快一些的)。普通的Web網站都是IO密集型的程序,瓶頸在MySQL上,所以體現不出PHP的性能劣勢。但在密集計算方面比C/C++、Java等靜態編譯語言差幾十倍甚至上百倍。另外使用設計非常復雜的開發框架,如Symfony、Laravel等,程序性能也會明顯下降。
現在隨著PHP越來越流行,像Facebook、新浪微博這樣超大型規模的網站都在使用PHP。PHP語言性能問題就越來越嚴重了。Facebook有幾十萬臺服務器,如果現有的PHP程序可以提升一部分性能,將會節約大量的服務器資源。所以就有了HHVM、Hack。Hack為PHP增加了類型,HHVM是一個重新設計的PHP引擎,實際項目中使用HHVM可以提近70%的性能。實際項目70%性能提升這是一個什么概念?騰訊QQ農場最初使用PHP開發,后因為性能問題使用C語言重構,完成后性能提升了100%。
PHP官方也注意到了這個問題,所以就有了PHP7的開發計劃。最新公布的PHP7-alpha在WordPress項目中測試的表現已經超越了HHVM。未來PHP將會同時具備極高的開發效率和極高的性能,再結合Swoole做異步編程,PHP勢必會更加流行。
本文簡單介紹一下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降低了,所以總的耗時降低了不少)
三 hashtable桶內直接存數據
PHP5的hashtable每個元素都是一個 Bucket *,而PHP7直接存Bucket,減少了內存申請次數,提升了Cache命中率和內存訪問速度。
四 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指令,執行更快。
六 其他更多優化
除了上面5個主要優化點之外,PHP7還有其他更多的細節性能優化。如基礎類型int、float、bool等改為直接進行值拷貝,排序算法改進,PCRE with JIT,execute_data和opline使用全局寄存器等等。PHP7對性能的優化會繼續進行下去。
PHP7-alpha相比PHP5.6性能提升了近3倍。下面是WordPress在PHP7上的表現:
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()}
";
}
匿名類
$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的開發工作。
PHP的異步網絡通信擴展Swoole
PHP在大部分程序員印象中都是用來做Web網站的。PHP沒有像Python的Twisted、Tornado,Java的Netty、Mina,JavaScript的Node.js等框架,無法實現異步網絡通信程序。PHP的Swoole擴展就是為了彌補此項缺陷而誕生的開源項目。Swoole是一個標準的PHP擴展,為PHP提供了一系列異步IO、事件驅動、并行數據結構功能。
Swoole與Node.js非常相似,不同之處是Swoole在并行提供了底層支持。Node.js是一個單進程單線程的程序,在多核服務器上無法發揮全部CPU核的計算能力。需要程序員自行使用child_process/cluster擴展或者啟動多實例,使程序能夠利用到多核優勢。而Swoole在底層就支持了多線程/多進程,程序啟動后就會創建好多個IO線程和多個Worker進程。程序員僅需配置線程/進程數量即可。
使用Swoole開發的TCP服務器程序:
$serv = new swoole_server("127.0.0.1", 9501);
$serv->on("connect", function ($serv, $fd){
echo "Client:Connect.
";
});
$serv->on("receive", function ($serv, $fd, $from_id, $data) {
$serv->send($fd, $data);
});
$serv->on("close", function ($serv, $fd) {
echo "Client: Close.
";
});
$serv->start();
Swoole同樣也內置了http_server和WebSocket服務器的支持。swoole_http_server與傳統的php-fpm不同,它是在PHP內進行事件循環的,基于swoole_http_server完全可以開發出類似Java應用服務器一樣,可以控制完整對象生命周期的程序。swoole_http_server天然支持異步IO,可以很方便的實現支持大量TCP連接的Comet服務。swoole_websocket_server可以用來實現支持Web實時推送的程序。
使用Swoole的Web服務器程序:
$http = new swoole_http_server("0.0.0.0", 9501);
$http->on("request", function ($request, $response) {
$response->header("Content-Type", "text/html; charset=utf-8");
$response->end("
$http->start();
PHP的未來
可以預見PHP語言未來會在性能方面有明顯的提升,越來越接近C/C++、Java等靜態編譯語言。再加上Swoole擴展,PHP的使用范圍可以擴展到移動通信、云計算、網絡游戲、物聯網、車聯網、智能家居等領域。
PHP雖然未必是最好的編程語言,但PHP在向著這個方向在發展。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21137.html
摘要:示例代碼斐波那契數列復制代碼復制代碼這里,給定規模,計算所需的時間為計算的時間和計算的時間的和。示例代碼復制代碼復制代碼同樣是斐波那契數列,我們使用數組來存儲計算結果,這樣算法復雜度優化為。算法適用于少量數據的排序,時間復雜度為。 原文:http://www.cnblogs.com/gaochundong/p/complexity_of_algorithms.html為什么要進行算法分...
摘要:對于這一問題企業一般多會采用其他技術,比如使用或者其他語言。但是有了之后,由于底層全是用語言實現,其出色的性能深受追捧。由于以前適用場景的局限性比較大,所以會有說重新定義了的說法。到這里的環境已經搭建完成了。 Swoole 是一個 php 的擴展,它的核心目標就是解決 php 在實現一些高訪問 server 服務中可能遇到的一系列問題,這些問題用原生的 php 往往并不能很方便高效的解...
摘要:服務重點基本概述協議是基于的一種新的網絡協議。被調用者通過狀態通知機制等來通知調用者,或通過回調函數來處理結果阻塞和非阻塞關注的是調用者等待被調用者返回調用結果時的狀態。 一、PHP7源碼安裝和Swoole源碼編譯安裝 1.1 PHP7源碼安裝 1.1.1 獲取源碼與安裝 ????獲取PHP7源碼:www.php.net tar -xzvf ... # 解壓命令 ./configur...
摘要:的為提供了版本,軟件源安裝的默認以的狀態運行在,比使用以的方式性能更好。 Ond?ej Sury 的 PHP PPA 為 Ubuntu 16.04/14.04 提供了 PHP7.2 版本,軟件源安裝的 PHP 默認以 Unix Socket 的狀態運行在 /run/php/php7.2-fpm.sock,比使用 TCP 以 localhost:9000 的方式性能更好。 1、安裝軟件源...
閱讀 2721·2023-04-26 02:28
閱讀 2551·2021-09-27 13:36
閱讀 3123·2021-09-03 10:29
閱讀 2751·2021-08-26 14:14
閱讀 2101·2019-08-30 15:56
閱讀 830·2019-08-29 13:46
閱讀 2609·2019-08-29 13:15
閱讀 454·2019-08-29 11:29