Optimize PHP, Apache & MySQL for performance « webjawns.com
http://webjawns.com/2010/01/optimize-php-apache-mysql-with-tuner-scripts-best-practices-and-more/
標籤: PHP
GD vs. Imagick (ImageMagick)
由於之前聽到網路上傳言 ImageMagick 函式庫的效能比 GD 還要好,不過找不到實在測試資料,所以自己來跑測試。
測試方式是由自己的一張全景照片 (512 x 512, 340KB) 分別用 GD 與 ImageMagick 的縮圖函式進行縮圖 (256 x 256),並紀錄執行函式所需要的時間。
產生縮圖用的程式碼分別如下:
Imagick.php:
<?php
function mtime()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$img = new Imagick();
$img->readImage('lenna.jpg');
for($a=0;$a<5;$a++){
$start = mtime();
$img->resizeImage(256,256,Imagick::FILTER_LANCZOS,1);
$stop = mtime();
echo ($stop - $start)."n";
exec('sleep 1');
}
$img->writeImage('s_imagick.jpg');
$img->clear();
$img->destroy();
?>
gd.php:
<?php
function mtime()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$src = imagecreatefromjpeg("lenna.jpg");
$thumb = imagecreatetruecolor(256,256);
$src_w = imagesx($src);
$src_h = imagesy($src);
for($a=0;$a<5;$a++){
$start = mtime();
imagecopyresampled($thumb, $src, 0, 0, 0, 0, 256, 256, $src_w, $src_h);
$stop = mtime();
exec('sleep 1');
echo ($stop - $start)."n";
}
imagejpeg($thumb, "s_gd.jpg");
?>
由於 PHP 原本的 time() 精確度只有到秒,對於這種小圖檔實在不夠用,於是找了 microtime() 來紀錄時間,呼叫 mtime() 以後會傳回當時的毫秒數並以 float 儲存,縮圖完畢在將結束時間與開始時間相減取得執行時間。
分別執行五次並紀錄結果。
使用 ImageMagick 函式庫:
0.050060033798218 0.048804998397827 0.051737070083618 0.048964977264404 0.048758983612061 平均:0.0496652126312256 秒
使用 GD 函式庫:
0.094849109649658 0.095477104187012 0.096488952636719 0.097059011459351 0.098549127578735 平均:0.096484661102295 秒
接下來比較原始圖檔以及縮圖品質。

原始圖 340 KB (點圖放大)
ImageMagick resizeImage() 產生出來的縮圖 50 KB
GD imagecopyresampled() 產生出來的縮圖 12 KB
產生出來的縮圖感覺 ImageMagick 的銳利度較高,可由帽子上的紋路看出。在這次測試時 ImagickMagic 些微勝出。
前一次測試時使用相機拍攝的 2.7M 全景圖製作 3/10 的縮圖,反而是 ImageMagick 較慢,時間接近 GD 的二倍,但是銳利度仍然是 ImageMagick 較高。但 ImageMagick 的銳利度是可以調整的,如果將銳利度降低不知速度是否會加快。
縮短網址 vs. Hash
一直到剛剛才想通為什麼大多數的縮短網址會使用 Hash 產生 key,果然不先死過一次不知道為什麼要這樣作。
先從 key 開始起吧,為了讓 key 更短通常會使用更多的文字或符號,從數字、英文大小寫甚至特殊符號。假設使用數字和英文大小寫作組合,每一位數都有 62 種組合 (10 + 26 + 26),用四個位數的話可以儲存約一千五百萬比資料,這對我這種小網站應該很夠用了。
還沒想通資料量和 hash 有何關係?那就來看看新增時到底要作哪些事情:
- 查詢資料是否已經存在
- 產生網址與 key 的對應
- 儲存結果
問題很明顯出在第一步驟,一千萬筆資料 query 一次到底要花多久的時間?有作索引也要花超過十秒,沒作索引花個半小時可能也算快。
如果將步驟改成這樣:
- 將網址作 Hash
- 使用 Hash 的結果查詢資料是否存在
- 檢查是否發生碰撞
- 儲存結果
在第一步先產生 hash 結果就可以減少搜尋的範圍,範圍縮小就可以減少第二步驟查詢所需要的時間。
現在開始後悔沒有好好學演算法了,我要怎麼自己寫一個 hash 函式出來啊???
Disable PHP register_globals
Code for disable PHP register_globals in PHPWind forum:
if(ini_get('register_globals')){
foreach($GLOBALS as $key=>$val){
if(!in_array($key,array('GLOBALS','_POST','_GET','_COOKIE','_SERVER','_FILES','wind_in'))){
${$key}='';
}
}
}
SQL Injection Note
Code from PHPWind forum in global.php:
set_magic_quotes_runtime(0);
if(!get_magic_quotes_gpc()){
Add_S($_POST);
Add_S($_GET);
Add_S($_COOKIE);
}
Add_S($_FILES);
function Add_S(&$array){
foreach($array as $key=>$value){
if(!is_array($value)){
$array[$key]=addslashes($value);
}else{
Add_S($array[$key]);
}
}
}

