為什么php不適合做計算密集型業務?
PHP即“超文本預處理器”,是一種通用開源腳本語言。PHP是在服務器端執行的腳本語言,與C語言類似,是常用的網站編程語言。PHP獨特的語法混合了C、Java、Perl以及 PHP 自創的語法。利于學習,使用廣泛,主要適用于Web開發領域。
1.優點:開源 免費性 快捷性 [程序開發快,運行快,技術本身學習快]
1)跨平臺,性能優越,跟Linux/Unix結合別跟Windows結合性能強45%,并且和很多免費的平臺結合非常省錢,比如LAMP(Linux /Apache/Mysql/PHP)或者FAMP(FreeBSD/Apache/Mysql/PHP)結合,或者數據應用夠大可以考慮換 PostgreSQL或者Oracle,支持N種數據庫。(N >= 10)
2)語法簡單,如果有學習C和Perl的很容易上手,并且跟ASP有部分類似。有成熟的開發工具,比如NuPHPed,或者Zend Studio等等,再Linux平臺下可以使用Eclipse等等。
3)目前主流技術都支持,比如WebService、Ajax、XML等等,足夠應用。
4)有比較完整的支持,比如使用ADODB或者PEAR::DB做數據庫抽象層,用Smarty或者smart template做模板層,如果是PHP 5.1的話,還能夠使用PDO(PHP Data Object)來訪問數據庫。
5)有很多成熟的框架,比如支持MVC的框架:phpMVC,支持類似ASP.net的事件驅動的框架:Prado,支持類似Ruby On Rails的快速開發的框架:Cake等等,足夠滿足你的應用需求。
6)PHP 5已經有成熟的面向對象體系,能夠適應基本的面向對象要求。適合開發大型項目。
7)有成熟的社區來支持PHP的開發。
8)目前已經很多大型應用都是使用PHP,比如淘寶網、Yahoo、163、Sina等等大型門戶,很多選用PHP來作為他們的開發語言,所以大型門戶都能夠選用它,我想足夠能夠你的使用了。
9)有很多開源的框架或開源的系統可以使用,比如比較知名的開源框架有Zend Framework、CakePHP、CodeIgniter、symfony等,開源論壇有Discuz!、Phpwind等,開源博客 WordPress,開源網店系統如Ecshop、ShopEx等,開源的SNS系統如UCHome、ThinkSNS等。
10)使用成本低 (linux apache mysql php內核)
2.缺點
1)函數命名不規范 駝峰法和下滑線,傳參位置不一 你知道的
2)單線程 ; PHP本身,一直以來php就是個單進程的程序;雖然php的pthreads擴展早就有了。但是它不夠穩定,運行運行著就會莫名其妙的自己掛掉;php的擴展都是C寫的,這也就意味著任何一個擴展出現線程競爭資源控制問題都能讓整個掛掉
3)核心異步網絡不支持(當然在linux只有同步非阻塞網絡模型)。卻少了這個使得很難開發一個能夠承受大并發的網絡應用。傳統的網絡模型和io都阻塞的。這樣基本的編程的做法就是一個進程(或者線程)響應一個用戶鏈接請求。因此無法完成像實時網游那樣需要成千上萬網絡連接的任務。盡管php也有Libevent、eio擴展對此算是某種程度上面的彌補,但是感覺都不是那么完善
4)只支持web開發,不方便做 .exe文件,不方便做桌面應用程序. 不方便做手機程序.
5)不適合做爬蟲、自動運行腳本.科學運算項目,這語言基本構架就不適合,雖然有很多方法實現。
6)后期維護困難。后期提速空間局限性較大。
在對PHP有一個大致的認識以后,我們來了解一下為什么說PHP慢?
PHP的慢是相對于C/C++級別的語言來說,事實上,PHP語言最初的設計,就不是用來解決計算密集型的應用場景。我們可以這樣粗略理解為,PHP為了提升開發效率,而犧牲了執行效率。
我們知道PHP一個很大的特點,就是弱類型特性,也就是說,我可以隨意定義一個變量,然后給它隨意賦值為各種類型的數據。以一個int整型數字為例子,在C語言中:
int num = 200; // 通常是4字節
但是,如果是PHP定義了一個同樣的變量,實際對應的存儲結構則是:
這個結構體將會占據遠比C變量多得多的內存,PHP中定義方式如下:
$a = 200; //這變量將實際占用對比C變量很多倍的存儲空間。
其實對PHP來說,無論存儲什么類型的數據,都是用上述“通殺”的結構體實現。為了兼容PHP程序員的變量類型“亂入”,PHP做到了對開發者的友好,但是對執行引擎很殘酷。單個變量內存消耗可能還不明顯,一旦用到PHP的數組等,則復雜度指數上升(數組的實現是HashTable)。然后,Zend引擎執行時,將這些PHP代碼編譯為opcode(PHP的中間字節碼,格式有點類似于匯編),由Zend引擎逐行解釋執行。
無論是字符串的連接操作,還是數組的簡單修改等,幾乎都是“PHP程序員一句話,Zend引擎跑斷腿”的節奏。因此,同樣的操作,對比C來說,PHP消耗了更多的CPU和內存等系統資源。除此之外,還有內存自動回收、變量類型判斷等等,都會增加系統資源的消耗。
例如,我用純PHP實現的快速排序函數和原生sort函數,排序10000個整型數字,來做一個耗時對比,結果如下:
原生的sort耗時3.44 ms,而我們自己實現的PHP函數sort則是68.79 ms。我們發現,兩者執行效率差距巨大。我的測試方式,是計算函數執行前后的時間間隔,而不是整個PHP腳本從啟動到結束的時間。PHP腳本啟動和關閉過程,本身有著一系列的初始化和清理工作,也會占據不少的耗時。
通常情況下,PHP執行效率的排行是:
最快的是PHP語言結構(isset、echo等),PHP語言的一部分(它們根本不是函數)。
然后比較快的就是PHP的原生和拓展函數。PHP拓展,基于Zend API之上,用C實現的功能,執行效率和C /Java是屬于同一個數量級的。
真正慢的就是,我們通過PHP自己寫的代碼和函數。例如,假如我們使用的比較重的純PHP實現的框架,因為框架本身的模塊很多,所以,會明顯拖累語言層面的執行效率,同時占據更多的內存。(國內的Yaf框架,以拓展的方式實現,因此執行效率遠快于純PHP寫的框架。
在一般情況下,我們并不推薦用過PHP實現邏輯復雜計算類型的功能,尤其是Web系統流量比較大的場景下。因此,PHP程序員應該對PHP的各種原生函數和各類拓展有一個比較廣泛的了解,在具體的功能實現場景中,尋求更原生的解決方案(原生接口或者拓展),而不是自己寫一堆復雜的PHP代碼來實現這類型功能。
如果有足夠的PHP拓展開發實力,將這類型業務功能重寫為一個PHP拓展,也會大幅提升代碼的執行效率。這是一個非常不錯的方式,也被廣泛應用PHP優化中。但是,自己編寫的PHP業務拓展的缺點也很明顯:
拓展開發耗時比較長,需求變更的時候修改也復雜,寫得不好可能會影響Web服務穩定性。(例如,在Apache的worker模式下,多線程場景下掛掉,會影響同一個進程下的其他正常子線程。如果是多線程的Web模式,編寫拓展還需要支持線程安全)
拓展在PHP版本升級的時候,可能需要做額外的兼容工作。
人員變動后的維護和接手成本也比較高。
實際上,在互聯網一線企業中,更常見的解決方案,并非增加PHP拓展,而用C/C 獨立寫一個服務server,然后PHP通過socket和服務server通信來完成業務處理,并不將PHP本身和業務耦合在一起。
不過,Web服務大部分的性能瓶頸都在網絡傳輸和其他服務server的耗時上(例如MySQL等),PHP執行的耗時在整體耗時的占用比例非常小,所以從業務角度來說,影響可能并不明顯。