回覆列表
  • 1 # 籠行千里

    PHP的慢是相對於C/C++級別的語言來說,事實上,PHP語言最初的設計,就不是用來解決計算密集型的應用場景。我們可以這樣粗略理解為,PHP為了提升開發效率,而犧牲了執行效率。

    我們知道PHP一個很大的特點,就是弱型別特性,也就是說,我可以隨意定義一個變數,然後給它隨意賦值為各種型別的資料。以一個int整型數字為例子,在C語言中:

    1

    int num = 200; // 通常是4位元組

    但是,如果是PHP定義了一個同樣的變數,實際對應的儲存結構則是:

    這個結構體將會佔據遠比C變數多得多的記憶體,PHP中定義方式如下:

    1

    $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執行的耗時在整體耗時的佔用比例非常小,所以從業務角度來說,影響可能並不明顯。

  • 2 # 阿拉丁Dream

    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執行的耗時在整體耗時的佔用比例非常小,所以從業務角度來說,影響可能並不明顯。

  • 中秋節和大豐收的關聯?
  • 我好像得厭食症了,我該怎麼辦?