這幾天在測試我們目前的php框架時發現,框架層加載php文件的時間很長,最終發現是因為各種require_once導致整個加載時間變長,如果不使用eaccelerator的情況下,在虛擬機上測試可能會到50-60ms,使用了ea之後,可以降到10-20ms,但是這個消耗還是比較大的,有什麼辦法可以解決嗎?
正好這兩天看到hiphop的文章,所以決定使用它來試一下,最終發現代價太大了,修改一個文件要把整個工程全部編譯一次,並且它生成的程序是http協議的,我們現在只是需要一個fastcgi服務器就行了,而且自己寫的各種擴展完全無法使用了,所以這條路基本上否定了。
雖然hiphop這條路走不通,但是卻給我一個啟示,既然造成加載慢的原因是require_once導致的,那干脆寫個腳本,把目前的所有代碼都merge成一個大的文件不就行了(因為我們的框架是rpc的,因此只有一個入口,index.php,其他的代碼裡全是class和function,不存在直接的調用邏輯,因此merge以後不會有任何影響)。具體的操作如下:
1、將所有的require_once行刪除,換成|空行
2、將文件開頭的<?php行換成空行
3、記錄每個文件在merge後的文件裡的offset,將這個信息輸出在merge後的文件尾,這個是用於修正日志的,因為merge完了之後,日志打印出來的信息都是那個merge完的文件以及行數,這對於線下查日志沒有任何幫助,因此需要修改日志輸出類,根據merge後的行數對日志進行修正。
做完之後,實際測了一下,發現如果不使用ea的話,框架的消耗基本在3-5ms,如果使用了ea,反而在5-6ms,去看了一下ea的代碼,發現原來它是將解析出來的op_array經過分類存儲,然後每次調用zend_compile時,再把這些東西重新拷貝再返回,這個過程並不比zend_compile實際去編譯快,而且還有許多額外的檢查,因此反而不如直接使用php-cgi。
另外在測試時發現php一個很奇怪的現象
class A extends B
{
}
class B{}
這段代碼是可以的,
但是
class A extend B{}
class B extend C{}
class C{}
這樣的代碼就會出錯了www.2cto.com
注:後來又測了一下autoload方式,發現比打成一個文件慢很多,在只自動加載一兩個類的情況下,某個特定請求需要執行20ms左右,而打成一個只需要5ms左右
摘自 無心雲