2014年7月6日

用資料表導向法改寫 switch。

簡單的 switch 改用資料表導向法改寫,重複代碼更少。

原本的寫法如下,此方法大概使用了30行左右,且有大部份的重複代碼。
function getDayOfWeek1($type)
{
    switch ($type) {
        case 1:
            $string = "一";
            break;
        case 2:
            $string = "二";
            break;
        case 3:
            $string = "三";
            break;
        case 4:
            $string = "四";
            break;
        case 5:
            $string = "五";
            break;
        case 6:
            $string = "六";
            break;
        case 7:
            $string = "七";
            break;
        default:
            throw new Exception("unknown item type");
            break;
    }
 
    return $string;
}

改用資料表導向的方式改寫後,方法的行數約20行,且新增一個方法所需要新增的程式碼更少。
function getDayOfWeek2($type)
{
    $table = array(
        1 => "一",
        "二",
        "三",
        "四",
        "五",
        "六",
        "七",
    );
 
    if (isset($type, $table)) {
        $string = $table[$type];
    } else {
        throw new Exception("unknown item type");
    }
 
    return $string;
}

接著測試一下兩者的效能,利用PHP執行下列的結果

$start = microtime(true);
for ($i=1; $i <= 90000; $i++) {
    $type = mt_rand(1, 7);
    getDayOfWeek1($type);
}
$end = microtime(true) - $start;
echo $end."\n";
// 0.042860984802246
 
$start = microtime(true);
for ($i=1; $i <= 90000; $i++) {
    $type = mt_rand(1, 7);
    getDayOfWeek2($type);
}
$end = microtime(true) - $start;
echo $end."\n";
// 0.12082099914551

方法一的執行效率比方法二高得多,幾乎是二到三倍,隨著判斷式的增加,甚至可以到五倍左右。

雖然在閱讀上方法二比方法一可能更一目了然,但是實際執行的結果卻是方法一比較高效率。

隔天早上起床後,想想為什麼會變慢的原因,赫然發現應該是建立資料表查詢用的陣列每次都重新建立,接著將該變數加上 static 後,兩個方式的查詢時間就差不多了,用空間換時間的典型例子。