PHP載入大檔案時require和file_get_contents的效能對比
在開發過程中發現,用require來載入一個很大(幾百K,甚至幾兆)的配置檔案時,會造成響應超時。如果把這個配置檔案的內容序列化後,用file_get_contents獲取檔案然後反序列化的方法來載入,就會快很多。
經過近兩週的研究,大概知道了其中的原因。
首先,還從PHP的流程說起,PHP其實有兩個流程,一個是啟動的流程,一個是響應請求的流程。PHP作為Apache的一個模組,向Apache註冊了兩個函式,一個是Aapche啟動的時候執行的函式:sapi_startup;一個是Apache接收到請求的時候呼叫的函式:php_handler
啟動的流程:
Apache啟動
-> sapi_startup
-> php_module_startup (PHP啟動總開關)
-> zend_startup (啟動Zend引擎,包括初始化全域性變數,初始化 compile 和 execute 函式
相應請求的流程:
Apache收到請求
-> sapi_startup
-> zend_activate (包括初始化編譯器、初始化執行器、啟動掃描器)
-> zend_compiler (語法分析、語意分析、生成opcode)
-> zend_execute (執行每個opcode)
-> zend_deactive(清理本次請求用到的資料)
如果遇到 require 或者 include 之類的函式時,會 從 zend_execute 階段重新回到 zend_compiler 階段,開始解釋PHP,執行PHP的過程。
除了 zend_compiler 和 zend_execute 階段之外,require 和 file_get_contents 的開銷基本是一樣的。
而且我們伺服器上安裝了apc擴充套件,就是說 zend_compiler 階段可以認為兩者也是一樣的。
那他們的效能九差在zend_execute階段了。
首先,讓我們用vld擴充套件檢視一下兩個檔案生成的opcode的數量,因為這個是execute的輸入。
結果顯示,require 生成的opcode數量為2萬多個,大多是 ADD_ARRAY_ELEMENT,就是構造資料;而file_get_contents生成的opcode只有6個;
然後再來對比執行的效率:
這兩個函式的執行可以分成兩部分:讀取檔案和構造配置檔案裡面的陣列;
先說讀取檔案,require讀取的機制是,以8192位元組大小的buffer迴圈將檔案讀入記憶體;而file_get_contents使用的是mmap,直接將檔案對映到了虛擬記憶體當中。這樣的話,require會比file_get_contents多出大量的系統呼叫。而file_get_contents無需作這麼多使用者態和核心態的切換工作。這一步,file_get_contents勝出一籌;
再來看構造陣列,require構造的機制是生成2萬多個opcode,然後一次執行這些opcode;而file_get_contents使用的是unserialize函式,他對傳入的文字進行解析,然後逐級構造成陣列。他們構造陣列的思路是一樣的,但是require每增加一級資料的開銷要比unserialize大;這一局也是 file_get_contents 略優;
但是,file_get_contents 在PHP內部是函式呼叫,而require是一個內建的opcode,所以呼叫file_get_contents時的開銷要比require略大;
所以,小檔案的時候,file_get_contents 讀取檔案時 記憶體對映的優勢發揮不出來,兩者部分伯仲;大檔案的時候,由於require要2K2K的迴圈呼叫read系統呼叫,就降低了他的效能。
相關文章
- 如何載入require.js檔案UIJS
- PHP file_get_contents 與 curl 效能比較PHP
- PHP:檔案載入PHP
- **對比$_POST、$GLOBALS['HTTP_RAW_POST_DATA']和file_get_contents('php://input')HTTPPHP
- [PHP檔案管理器]⑤--file_get_contents檢視檔案PHP
- PHP 5 與 PHP 7 的效能對比PHP
- PHP7.2、PHP7.1效能對比PHP
- .ts檔案和d.ts檔案對比
- Linux大檔案重定向和管道的效率對比總結Linux
- php手動載入檢視檔案PHP
- PHP檔案的自動載入(autoloading)PHP
- 載入Mapper對映檔案APP
- truncate 和 delete 的效能對比delete
- 臨時檔案的順序和絕對檔案號
- ext3,ext4,xfs和btrfs檔案系統效能對比
- 載入時間/效能
- 比對檔案sam檔案的解讀
- QT 檔案相對路徑載入QT
- smali檔案對比java檔案Java
- grep檔案比對
- 一對一影片app開發,如何分塊載入大檔案?APP
- php檔案下載PHP
- php 檔案下載PHP
- 強大的檔案對比工具Beyond Compare 4 for MacMac
- Profile配置和載入配置檔案
- 載入和儲存properties檔案
- js動態載入 js檔案和 css檔案JSCSS
- file_get_contents和fread的效能差別
- PHP寫入檔案PHP
- list集合、txt檔案對比的工具類和檔案讀寫工具類
- linux 檔案比對Linux
- 轉載.Linux三大檔案系統比較Linux
- 使用PHP下載檔案PHP
- PHP檔案下載原理PHP
- TIDB和MySQL效能對比TiDBMySql
- 4款主流PHP框架效能對比評測PHP框架
- mysql的innodb和myisam的dml效能對比MySql
- 大資料入門課程:Hadoop和spark的效能比較大資料HadoopSpark