PHP的效能演化(從PHP5.0到PHP7.1的效能全評測)

來源:互聯網
上載者:User

標籤:pcl   XML   查看   href   stack   class   bytecode   cto   bcmath   

本文是最初是來自國外的這篇:PHP Performance Evolution 2016, 感謝高可用架構公眾號翻譯成了中文版, 此處是轉載的高可用架構翻譯後的文章從PHP 5到PHP 7效能全評測(含未發布的JIT版PHP 8對比), 稍微調整了格式而成。

導讀:PHP 是 Web 開發最常用的語言,每個大版本的更新都帶來不少新特性和效能提升。特別是 PHP 7.0 的發布,帶來 PHP 效能飛躍。本文作者對各個 PHP 版本進行了 CPU 效能基準測試,並且帶來了PHP下個大版本的訊息。本文中文版由高可用架構志願者翻譯。

自 1994 年 Rasmus Lerdorf 建立 PHP 以來, PHP 語言經曆了許多改進,其中效能是開發人員在評估新版本時考慮的主要標準之一。

閱讀這篇文章,可以瞭解從 PHP 5 到 7(包括 7.1)的效能提升,同時也將瞭解到即將加入到 PHP 8 的實驗性的 JIT 分支版本的效能。

簡介

本文將根據時間作出更新,增加更多資訊和基準測試結果,包括尚未發布的新版本,以便更好地瞭解多年來 PHP 效能演變。如果您有更正或建議改進,請在文後留言。

自 1994 年 Rasmus Lerdorf 建立 PHP 以來, PHP 語言經曆了激烈的演化。雖然第一版是一個簡單的一人開發的 CGI 程式,Rasmus Lerdorf、Andi Gutmans 和 Zeev Suraski 加入了該語言的第三個版本的開發,並根本性重新設計。從那之後, PHP 開發組也建立並發展起來。

隨著項目的發展,由於 PHP 3 天然的可擴充性, PHP 在核心和附加擴充開發的功能得到了蓬勃發展,如網路通訊,解析,緩衝和資料庫支援。

語言本身也在發展,帶來了一系列的改進。這包括支援物件導向的結構,例如類,介面, traits,閉包等。

對於許多開發人員來說,僅有新功能是不夠的。隨著語言越來越受歡迎, PHP 社區對於提供更好效能,可擴充性和更少記憶體使用量的需求越來越強烈。

PHP Team Dev近 20 年來一直致力於解決這些需求,雖然 PHP 3 的引入大大提高了效能,但直到 Andi Gutmans 和 Zeev Suraski 引入 Zend Engine 並發布 PHP 4, PHP 的效能才開始變得正式起來。

2000 年推出的新的記憶體編譯器和執行器模型大大提高了 PHP 的效能(提高了 5 倍甚至 10 倍),並首次被正式的 Web 應用程式和網站所使用。我們可以說,今天 PHP 的成果遠遠超出了任何人在 PHP 項目誕生時的期望。

PHP 的蓬勃發展增加了改善效能的慾望。幸運的是, Zend Engine 中設計的模型為持續最佳化效能提供了良好的基礎。

雖然 PHP 5.0 沒有帶來實質性的效能提升,並且在某些情況下甚至比 PHP4 更慢,一個由 Dmitry Stogov 領導的團隊在社區的大力協助下已經在後續版本中不斷最佳化語言,在 PHP 5.6 發布的時候,在大多數情況下,效能提升在 1.5x 和 3x 之間。

2015 年 12 月, PHP 7.0 取得了重大突破。 2016 年 12 月,7.1 版本也帶來了一系列增強功能。

PHP 8 效能展望

這是一個前途光明的版本,目前正在開發當中,由 Zend 的 Dmitry Stogov 主導。雖然它是基於 PHP 7.1 版本基礎,但實際版本號碼尚未定義,所以本文稱這個版本為“實驗 JIT”分支下。

關鍵功能 JIT(Just-In-Time)編譯,是一種將代碼轉換為另一種位元組碼(比如運行它的機器 CPU 的本地代碼)的技術。 JIT 可以使程式運行更快。

本文涵蓋了幾個基準測試的結果,從 PHP 5 的第一個版本到 PHP 的實驗性 JIT 分支版本,PHP 5 之前的版本效能本文不作介紹。

在寫這篇文章的時候,我們很難確定 PHP 8 之前是否會有另一個主要版本,比如 PHP 7.2。但是可以假設在 PHP 8 發布時,它已經包括當前實驗版 JIT 分支的強大功能。

PHP 效能評估

本文只運行純 CPU 任務指令碼的基準測試(不需要I / O操作的任務例如訪問檔案,網路或資料庫連接)。

使用的基準測試指令碼如下所示:

  1. bench.php 可在PHP原始碼的 php-src/Zend 目錄
  2. micro_bench.php 也可以在 PHP 原始碼發布的 php-src/Zend 目錄中找到
  3. mandelbrot.php https://gist.githubusercontent.com/dstogov/12323ad13d3240aee8f1/raw/37fed3beb7e666b70e199bcf361af541b3c30d2d/b.php

基準指令碼僅使用每個PHP主要版本的最新小版本運行。因此,測試的版本如下:

  1. 5.0.5
  2. 5.1.6
  3. 5.2.17
  4. 5.3.29
  5. 5.4.45
  6. 5.5.38
  7. 5.6.28
  8. 7.0.13
  9. 7.1.0
  10. PHP-JIT(JIT實驗分支)

當然,我想確定,我們在相同的基準上運行所有小版本,例如在 5.3.0 到 5.3.29 之間。結果是令人信服的:效能方面的主要增強不是由小版本帶來的,而是主要版本號碼的變化,例如從 PHP 5.4 到 PHP 5.5,或從PHP 5.6 到 PHP 7。

小版本沒有顯示任何明顯的效能改進。這意味著相同的指令碼應該以相同的速度運行,無論您使用 PHP 5.4.0 還是 PHP 5.4.45。

您可以查看基準進程部分,詳細說明主機系統的設定,各個基準的運行方式以及如何解釋時序結果。

純 CPU 基準測試結果

這部分給出了每個 PHP 版本的基準測試結果。

每個基準列顯示 3 個值:

  • 時間: 執行時間,以秒和毫秒為單位
  • %rel, gain:相對於以前的版本收益的執行時間。 在下面的表格中,例如,%rel。 bench.php 和版本 5.3.29 的收益是 31.89%,意味著該指令碼比 5.2.17 版本運行快 31.89%。
  • %abs, gain:與 PHP 5.0 相比指令碼啟動並執行收益。 如果你看看bench.php 和實驗性的 JIT 分支的這個列的交集,你會注意到,對於這個特定的測試基準,PHP 8 比 PHP 5.0 快 41 倍以上。

純CPU基準測試的結果如下所示:

 

CPU基準測試



(1)測試不能在 5.3 之前的版本上運行,因為它使用了尚未實現的對象功能。
(2)此列中的結果有點偏頗,因為基準需要至少 PHP 5.3 運行。把它們當成純粹說明,因為他們不能與 PHP 5.0 效能進行比較。
(3)這是一個 mandelbrot.php 指令碼的修改版本,它運行得太快,在 7.1.0 和實驗 JIT 分支無法準確的統計時間,我們在指令碼中運行計算 100 次而不是 1 次。

 

當然,這些都是純 CPU 的基準測試。它們不涵蓋 PHP 效能的所有方面,它們可能不代表真實情況。但是結果足夠顯著,足以說明幾個方面的問題:

  • PHP 5.1 將 PHP 5.0的 效能提高了一倍多
  • 5.2 和 5.3 帶來了他們自己的一些效能增強,但他們沒有像5.1版本那樣引人注目。
  • 5.4 版本是一個大的效能改進。(這裡有我曾經分享過的PHP5.4的效能最佳化的演講PPTPHP-5.4 Performance)
  • opcache 擴充外掛程式與 5.5 和 5.6 版捆綁在一起。當相同的指令碼在 Web 服務器連續運行時,由於更快的代碼載入會帶來效能增強。但是,opcache 不會真正顯示其在CLI模式下執行指令碼的優勢。
  • PHP 7.0 是效能方面的一個重大突破。 Zend Engine 已經完全重新設計,我們可以在這裡看到這項工作的結果。(這裡有我曾經分享過的PHP7的效能最佳化的演講的PPT The secret of PHP7′s Performance )
  • PHP 7.1 在 opcache 擴充中引入了 opcode 最佳化。這再次解釋了上述表格中當與 7.0 相比時,效能的增益。(這裡有我曾經分享過的PHP7.1的效能最佳化的演講PPTPHP 7.1′s New Features and Performance
  • 實驗 JIT 分支是另一個重大突破,JIT 可以對現有代碼提供很大的效能改進,但在某些情況下,你可能會注意到速度提高只有幾個百分點,在最壞的情況下,它甚至可能會變慢,因為編譯不會產生更快的代碼。請記住,此功能目前正在開發中。

本節介紹了 3 個純 CPU 基準測試指令碼的結果。在運行通常執行的以資料庫或檔案訪問典型情境的 PHP 應用程式時,它不會給出同樣的數字,但我認為他們能夠代表您對代碼的某些部分期望的效能改進。

PHP 每個版本的效能提升

PHP 5 相比 PHP 4 帶來了明顯的改進。 Zend Engine 是 PHP 解譯器的核心,它已經完全重新設計( Zend Engine 2),為將來的增強功能奠定了基礎。本文不多介紹 PHP 4 和 PHP 5 之間的差異,只簡要概述的 PHP 5.0 之後發生了什麼。

以下部分列出了在後續 PHP 版本中的改進。請注意,這裡僅列出影響 PHP 核心的修改。有關更完整的描述,請查看 PHP 5 和 PHP 7 的change log。

PHP 5.1

  • Compiled variables
  • Specialized executor
  • Real-path cache
  • Faster switch() statement handling
  • Faster array functions
  • Faster variable fetches
  • Faster magic method invocations

PHP 5.2

  • New memory manager
  • Optimized array/HashTable copying
  • Optimized require_once() and include_once() statements
  • Small optimization on specific internal functions
  • Improved compilation of HEREDOCS and compilation of interpolated strings

PHP 5.3

  • Segmented VM stack
  • Stackless VM
  • Compile-time constants substitution
  • Lazy symbol table initialization
  • Real-path cache improvement
  • Improved PHP runtime speed and memory usage
  • Faster language parsing
  • Improved PHP binary size and code startup

PHP 5.4

  • Delayed HashTable allocation
  • Constant tables
  • Run-Time binding caches
  • Interned Strings
  • Improved the output layer
  • Improved ternary operator performance when using arrays

PHP 5.5

  • Improved VM calling convention
  • OPcache integration
  • Other misc. optimizations to the Zend Engine

PHP 5.6

  • Optimized empty string handling, minimizing the need to allocate new empty values

PHP 7.0

下面大部分列出的改進都與 Zend Engine 相關:

  • Core data structures re-factoring
  • Better VM calling convention
  • New parameters parsing API
  • Yet another new memory manager
  • Many improvements in VM executor
  • Significantly reduced memory usage
  • Improved __call() and __callStatic() functions
  • Improved string concatenation
  • Improved character searching in strings

PHP 7.1

  • New SSA based optimization framework (embedded into opcache)
  • Global optimization of PHP bytecode based on type inference
  • Highly specialized VM opcode handlers

PHP 8 / 下一代實驗性 JIT 分支版

  • Just-In-Time compiling
效能如何衡量

基準化比單純運行 Unix 時間命令來測量指令碼的執行有所區別。 這就是為什麼我經曆了以下步驟:

配置系統

首先我設定了一個具有以下特性的專用系統:

  • 一個帶有1個2.4GHz虛擬核心,2GB RAM和兩個SSD磁碟機的VPS,一個用於儲存作業系統資料,另一個用於儲存各種PHPyuan dai ma,二進位檔案和報告輸出
  • Debian Wheezy作業系統,版本3.2.82-1
  • Gnu C編譯器版本4.9.2-10(Debian Jessie發行版)
  • 雖然系統捆綁了Gnu C編譯器版本4.7.2,但需要升級到更新的版本。 實驗性 JIT 分支必須用Gnu C> = 4.8編譯。
編譯原始碼

在構建完整發行版之前,使用以下選項回合組態指令碼:

  1. --prefix=/usr/local/php
  2. --disable-debug
  3. --disable-phpdbg
  4. --enable-mysqlnd
  5. --enable-bcmath
  6. --with-bz2=/usr
  7. --enable-calendar
  8. --with-curl
  9. --enable-exif
  10. --enable-fpm
  11. --with-freetype-dir
  12. --enable-ftp
  13. --with-gd
  14. --enable-gd-jis-conv
  15. --enable-gd-native-ttf
  16. --with-gettext=/usr
  17. --with-gmp
  18. --with-iconv
  19. --enable-intl
  20. --with-jpeg-dir
  21. --enable-mbstring
  22. --with-mcrypt
  23. --with-openssl
  24. --enable-pcntl
  25. --with-pdo-mysql=mysqlnd
  26. --with-png-dir
  27. --with-recode=/usr
  28. --enable-shmop
  29. --enable-soap
  30. --enable-sockets
  31. --enable-sysvmsg
  32. --enable-sysvsem
  33. --enable-sysvshm
  34. --enable-wddx
  35. --with-xmlrpc
  36. --with-xsl
  37. --with-zlib=/usr
  38. --enable-zip
  39. --with-mysqli=mysqlnd

注意,在編譯舊版時,上面的一些選項需要被禁用或被其他替代,並且並不是所有的擴充都可用或可以被編譯。

運行基準測試

每個基準測試都使用 PHP CLI 專用指令碼運行,該指令碼遵循以下步驟:

使用 microtime()函數從內部擷取指令碼執行時間。 在此修改後,基準指令碼將如下所示:

  1. <?php
  2.     $__start__ = microtime( true );
  3.     /***
  4. original benchmark script code here
  5. ***/
  6.     fprintf( STDERR, microtime( true ) - $__start__);
  7.  ?>

執行 2 次運行,以確保 PHP 可執行檔和基準測試指令碼內容都在作業系統緩衝中
運行指令碼 5 次,並提取最小,最大和平均已耗用時間,如指令碼報告。 本文僅顯示平均已耗用時間,稱之為“指令碼已耗用時間”。

php.ini 檔案如下所示:

  1. engine = On
  2. short_open_tag = Off
  3. realpath_cache_size = 2M
  4. max_execution_time = 86400
  5. memory_limit = 1024M
  6. error_reporting = 0
  7. display_errors = 0
  8. display_startup_errors = 0
  9. log_errors = 0
  10. default_charset = "UTF-8"
  11.  
  12. [opcache]
  13. zend_extension=opcache.so
  14. opcache.enable=1
  15. opcache.enable_cli=1
  16. opcache.optimization_level=-1
  17. opcache.fast_shutdown=1
  18. opcache.validate_timestamps=1
  19. opcache.revalidate_freq=60
  20. opcache.use_cwd=1
  21. opcache.max_accelerated_files=100000
  22. opcache.max_wasted_percentage=5
  23. opcache.memory_consumption=128
  24. opcache.consistency_checks=0
  25. opcache.huge_code_pages=1
  26.  
  27. // PHP 8/Next only
  28. opcache.jit=35
  29. opcache.jit_buffer_size=32M
分析運行結果

使用 Unix time 命令來計時,輸出如下所示:

  1. $ time php bench.php
  2. real: 0m1.96s
  3. user: 0m1.912s
  4. sys: 0m0.044s

第一個值,real : 是命令開始到終止之間的時間(當你回到 shell 提示符)。

第二個值,user :說明在使用者模式中花費的時間(在我們的例子中,這是在 php 可執行檔中花費的時間)。

最後一個值 sys :說明在作業系統(核心)調用中花費的時間。這個值應該是最小的,但是如果你的代碼訪問緩慢的裝置結果會比較大。重負載的作業系統也可能影響此處報告的值。

在空閑系統上通常,數量(user + sys)應該非常接近 real。這是在上面的例子中的情況:user + sys = 1.956s,real 是 1.960s。 0.004s 的差異不屬於當前進程:它僅僅意味著作業系統執行任務所花費的額外時間,例如調度。

同一個指令碼在一個負載很重的系統上執行,並行編譯 3 個不同的 PHP 版本:

  1. $ time php bench.php
  2. real: 0m7.812s
  3. user: 0m2.02s
  4. sys: 0m0.101s

在這裡我清楚地看到,系統本身的重負載對使用的時間(也許在系統時間)有重大影響。

這就是為什麼我在這個基準中保留一個額外的值,作業系統開銷,這是調用的時間和(使用者+系統)時間之間的差。

在純 CPU 基準測試活動期間,我確保在 99% 以上的時間,這個值嚴格小於 100 毫秒,即使運行需要幾十秒鐘完成的指令碼。

結論

本文的目的是給你一個不同版本PHP效能的概述,從 5.0 開始,到當前正在開發的最新版本,使用一組已知的基準指令碼。

它還為您提供了由每個連續 PHP 版本解決的效能改進方面的列表。

本文將隨著新的 PHP 版本的公布而更新,並且將來會添加新的基準測試結果。 我也希望添加一些真實世界的 PHP 應用程式,如 WordPress 的基準測試結果。

如果您有任何問題或發現不準確,請隨時發表評論。 同時,與其他對 PHP 效能感興趣的開發人員分享這篇文章。

PHP的效能演化(從PHP5.0到PHP7.1的效能全評測)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.