使用 PHP Framework 的效能問題

PHP Framework 裡會大量使用 require_once(),由於需要判斷是否載入過檔案,require_once() 會使用 realpath() 取得檔案實際路徑資訊當作判斷條件,而這點會有效能上的問題。

其他人其實也遇過,參考:PHP Performance tip: require versus require_once,其中 comment 的部份也說明了目前 Google 到的方法是沒有用的。

FreeBSD libc 裡的 realpath(3) 會使用 lstat(2),而 FreeBSD 的 lstat(2) 因為用到 VFS_LOCK_GIANT(9),所以在 FreeBSD 上很多隻 PHP 同時用 realpath() 的時候效能並不好。

Linux 的 libc 據說沒這個問題 (我沒有實際去 trace libc code,聽別人轉述的),不過實際灌了一台 Debian 跑 PHP 發現解決了 lstat() 的問題後,require_once() 造成的效能問題還是很嚴重。

目前的解法與 Wikia 類似,想辦法讓 require_once() 能夠很快找到 code,不過還是得想辦法從 PHP 本身下手,改善 require_once() 的效能,讓 PHP Framework 發展的時候不用綁手綁腳。

PS:目前的方法是改掉 Zend Framework 裡面的 require_once(),由於我們有一個統一的 /pixnet,把裡面的程式碼全部都用絕對路徑。另外在 Autoload 的部份用 APC cache,避免再到 include_path 內重複尋找。

9 thoughts on “使用 PHP Framework 的效能問題”

  1. 关于require&require_once的性能问题已经在php5.2版本修正了,当然了,从根本上来说require_once是要比require慢,但这个对系统的影响几乎可以不考虑。

    相对于程序的健壮,所谓的损失我觉得可以不考虑,这就是为什么ZF里面都是require_once的原因,尤其是团队合作,你引我的文件,我引你的文件,很容易重复load。

    或者用xdebug测试一下。

  2. Hi, 我好少用php, 我想問用require_once 都是為了被免conflict, 為何不採用如C++ ifndefine 技考? 或者namespace? 是php 本身有技術限制做不到,還是performance 上require_once 比起我以上做法為好?

  3. require 跟 require_once 的效能比較其實多年以來都有人提及,Rasmus 也多次在他演講中的 slide 提出 profiling 的數據來做比較。

    有些 framework 的解決之道,是透過自製的 require 方式,來使用 'require' 又達到 'require_once' 的效果。

  4. 从另一方面来说, require_once / include_once 正好符合了 Lazy Loading 规则.

    但是过度的滥用则会如您所说, 导致性能失衡.

    BTW: OPCode 确实很好

  5. Zend Framework裡面大量使用到require_once這個問題我之前倒是沒有注意到,那您認為像是Code Igniter用$this->load的載入方式覺得怎麼樣?

    我之前看過幾篇比較,Zend Framework跟其他的Framework像是CakePHP比較起來,Zend Framework的速度還算是OK的。

Leave a Reply

Your email address will not be published. Required fields are marked *