簡單說說PHP優化那些事

Web開發者發表於2013-01-29

  我們在編寫程式時,總是想要使自己的程式佔用資源最小,執行速度更快,程式碼量更少。往往我們在追求這些的同時卻失去了很多東西。下面我想講講我對PHP優化的理解。優化的目的是花最少的代價換來最快的執行速度與最容易維護的程式碼。

  進行大範圍的優化,而不是死啃某些程式程式碼

  我這裡所說的優化,基本上都是從伺服器,Apache,資料庫這些方面來進行的優化,而並不是對你的PHP程式碼加以改進從而提高程式的執行速度,因為比起你將程式中的正則優化為字串處理函式從而提升程式速度來說,在大範圍內進行的優化所需要的代價要比這個小的多,而獲得報酬卻要豐厚的多。

  在非程式碼處進行優化有以下好處:

  1、通常情況下能夠大大提高效率

  2、不會危及到程式碼的完整性

  3、能夠快速部署

  快取技術

  下面來說說常用的快取技術,通過這些快取技術能夠大大的提高效率

  在說到快取技術的時候不得不提到memcached ,memcached是高效、快速的分散式記憶體物件快取系統,主要用於加速 WEB 動態應用程式。

  Memcached的原理

  memcached 是以守護程式方式執行於一個或多個伺服器中,等待接收客戶端的連線操作,客戶端可以由各種語言編寫(例如PHP)。PHP 等客戶端在與 memcached 服務建立連線之後,接下來的事情就是存取物件了,每個被存取的物件都有一個唯一的識別符號 key,存取操作均通過這個 key 進行,儲存到 memcached 中的物件實際上是放置記憶體中的,並不是儲存在 cache 檔案中的,這也是為什麼 memcached 能夠如此高效快速的原因。

  說完memcached,下面來說說常用的快取方法

  1、編譯與OPCODE快取

  因為PHP是解釋型的語言,所以每個PHP檔案在執行的時候都需要編譯後再執行,同一個檔案,不同的使用者訪問,或者同一個使用者不同時間訪問同一個檔案,每次都需要重新編譯然後執行,這樣就耗費了大量時間。

  通過編譯快取每個檔案在修改之後只編譯一次這樣就減少了檔案IO操作,使用者訪問後機器指令直接從記憶體中取出並執行而不是硬碟中讀出。

  最常見的PHP編譯快取工具有:APC,Accelerator,xcache

  2、全域性頁面快取– Squid Cache

  Squid Cache(簡稱為Squid)是一個流行的自由軟體(GNU通用公共許可證)的代理伺服器和Web快取伺服器,Squid作為網頁伺服器的前置cache伺服器通過快取相關請求來提高Web伺服器的速度。

  3、區域性快取之SQL快取

  在大多數應用程式中主要的瓶頸往往可以追溯到資料庫的操作中,一般都是因為複雜的資料庫查詢而耗費了大量時間,而SQL快取可以大大降低複雜查詢造成的負荷。

  SQL快取的例子(使用了memcached擴充套件)

  程式碼片段:

  $key = md5(“some sort of sql query”);

  if (!($result = memcache_get($key))) {

  $result = $pdo->query($qry)->fetchAll();

  // 快取查詢結果一小時

  memcache_set($key, $result, NULL, 3600);

  }

  4、區域性快取之程式碼塊快取

  為了優化PHP程式,有時候我們不得不優化一個個程式碼段來減少那麼一點點的執行的時間,但是比起優化複雜的不同的PHP程式碼段還不如通過快取來直接忽略這些程式碼段的優化,這樣做的好處是:

  1、能夠很快的看到效果

  2、不會破壞以前的程式碼

  3、速度要比優化程式碼要快得多

  程式碼塊快取的列子(同樣使用了memcached擴充套件)

  程式碼片段:

  function complex_function_abc($a, $b, $c) {

  $key = __FUNCTION__ . serialize

  (func_get_args());

  if (!($result = memcache_get($key))) {

  $result = //函式程式碼

  // 儲存執行結果1小時

  memcache_set($key, $result, NULL, 3600);

  }

  return $result;

  }

  當然除了上述方法外還可以用到檔案快取(將資料庫中的資料取出儲存在檔案中),還可以生成靜態HTML檔案等,但是這些方法的快取還是將檔案儲存在硬碟上而不是記憶體中。

  輸出控制

  除了上述快取技術外還可以通過輸出控制來讓程式執行的時間更少

  下面通過PHP與APACHE來說說輸出控制

  1、PHP輸出控制

  這裡最主要用到ob_start()以及PHP中的OB系列函式,這些函式可以做什麼呢?

  第一就是靜態模版技術。所謂靜態模版技術就是通過某種方式,使得使用者在client端得到的是由PHP產生的html頁面。如果這個html頁面不會再被更新,那麼當另外的使用者再次瀏覽此頁面時,程式將不會再呼叫PHP以及相關的資料庫,對於某些資訊量比較大的網站,例如sina,163,sohu。類似這種的技術帶來的好處是非常巨大的。

  程式碼示例:

  <?php

  ob_start(); //開啟緩衝區

  ?>

  php頁面的全部輸出

  <?php

  $content = ob_get_contents(); //取得php頁面輸出的全部內容

  $fp = fopen(“output.html”, “w”); //建立一個檔案,並開啟,準備寫入

  fwrite($fp, $content); //把php頁面的內容全部寫入output.html,然後……

  fclose($fp);

  ?>

  當然這個ob系列函式還有其他很多用處我就不在這裡一一說明了。

  2、apache輸出控制

  將SendBufferSize設定為頁面大小,這樣就能將頁面一次性放在傳送緩衝區從而增加處理速度。

  SendBufferSize 指令

  說明:TCP傳送緩衝區大小(位元組)

  語法:SendBufferSize bytes

  預設值:SendBufferSize 0

  作用域:server config

  狀態:MPM

  模組:beos, mpm_netware, mpm_winnt, mpmt_os2, prefork, worker

  這個指令設定伺服器的TCP傳送緩衝區的大小(位元組)。提高這個值會導致兩個後果:高速度和高潛伏時間(100ms左右)。如果設定為”0″,將使用作業系統預設值。

  通過原始碼方式編譯你的Apache/PHP/Database 可讓你的程式增加10–15%的速度

  下面再說說在程式碼優化的時候應該注意的

  1、短程式碼不等於快的程式碼

  很多人在寫程式時希望將程式碼寫的越簡潔越好,但是越短的程式碼有時候反而需要更長的執行時間,所以哪怕是用更多的程式碼也不使用速度慢的程式碼

  2、在寫程式的時候更應該注重程式的擴充套件性,而不是追求速度

  3、在優化你的程式碼之前,先看看跟資料庫有關的部分,因為大多數應用程式的瓶頸在資料庫而不是程式碼

  4、微優化得不償失

  什麼叫做微優化?就像前面所說的將正規表示式部分的程式碼改用字串函式代替。這樣做有以下缺點:

  (1)花費時間較長

  (2)不會解決你的效能問題

  (3)很有可能會破壞以前的程式碼從而產生未知的錯誤

  (4)付出大於回報

  這裡還不得不提到一個誤區,有些人為了讓程式更加優化,在分析業務邏輯的時候便將優化考慮在內了,從而為了得到更優的程式碼而改動業務邏輯。這是十分愚蠢的想法,因為程式的目的便是為了處理現實中遇到的問題,是為這些問題服務的,怎麼能本末倒置呢。

相關文章