Smarty是PHP語言裏面最經典的模板引擎,如果你曾經開發過PHP程序,那麼或多或少都有使用過它。Smarty在2010年發佈了第三版,Smarty 3用當下最新的PHP5進行了重構。它保留了原有的語法並加入了一些更現代的特性。
Twig是來自Symfony開發者,Twig作者將其定位成一個快速及功能強大的現代模板引擎。Twig有着許多與Smarty 3相似的特性,但爲了提高性能而稍微有些不同。
現在我們來將兩者進行一下性能對比測試:
測試
我們準備了較複雜的模板以便可以明顯看出程序執行的時間,以下是我們的代碼:
相同的功能,看起來Smarty實現更簡單些:
$data = json_decode(file_get_contents('data.json'), true);
require('smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->compile_check = false;
$start = microtime(true);
$smarty->assign($data);
$smarty->fetch('demo.tpl');
echo microtime(true)-$start;
Twig更復雜些:
$data = json_decode(file_get_contents('data.json'), true);
require('twig/Autoloader.php');
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('templates');
$twig = new Twig_Environment($loader, array(
'cache' => 'templates_c',
'autoescape' => false,
'auto_reload' => false,
));
$start = microtime(true);
$template = $twig->loadTemplate('demo.tpl');
$template->render($data);
echo microtime(true)-$start;
兩個程序都做了同樣的配置:關閉二次編譯、不顯示頁面,只留下執行時間的顯示。
從變量中獲取值
從變量中獲取值是比較常用的操作,在較複雜的模板開發中或許會用上幾百次。我們或許會認爲該操作的執行速度不需要依賴於模板,但不是的,模板引擎會在模板中用一些數據結構來存儲變量的值,所以獲取變量值的操作需要更簡單和快速的性能。下面我們將生成一個帶有10000個值的模板以比較性能。
Smarty:
{$var0}
{$var1} {$var2} {$var3} {$var4} ... |
Twig:
{{
var0 }} {{ var1 }} {{ var2 }} {{ var3 }} {{ var4 }} ... |
Result:
|
Compiling |
Execution |
Smarty 3.1.1 |
16.320 seconds |
0.058 seconds |
Twig 1.2.0 |
9.757 seconds |
0.083 seconds |
上面的表格演示了多次連續測試的平均值。我們可以看到程序已經編譯生成了1萬個變量的模板,Smarty在編譯的時候是遠遠落後於Twig。不過編譯僅僅是第一次訪問的時候執行,之後會一直使用編譯後的頁面,所以編譯後的頁面執行速度纔是更重要的。編譯後的執行時間,Smarty是比Twig快速了30%左右,
使用多次foreach來測試
一般開發中模板經常用到foreach,這裏我們用了1000個帶有十個元素的數組,來測試一下兩個模板引擎的foreach性能。
Smarty:
{foreach $array as $item}
{$item.id} {$item.title} {$item.var1} {$item.var2} {$item.var3} {$item.var4} {$item.var5} {$item.var6} {$item.var5} {$item.var6}
{/foreach}
Twig:
{% for item in array %}
{{ item.id }} {{ item.title }} {{ item.var1 }} {{ item.var2 }} {{ item.var3 }} {{ item.var4 }} {{ item.var5 }} {{ item.var6 }} {{ item.var5 }} {{ item.var6 }}
{% endfor %}
Result: .
|
Compiling |
Execution |
Smarty 3.1.1 |
0.065 seconds |
0.009 seconds |
Twig 1.2.0 |
0.131 seconds |
0.082 seconds |
這裏有個令人驚訝的情況:編譯後的Smarty模板比Twig執行快近10倍以上。與此同時,就算是編譯+執行一起計算,Smarty還是會比Twig快。我們可以推測模板編譯器而言,Smarty初始化比Twig要快許多。Smarty在上個測試中執行中稍微慢些,但在小型模板中幾乎無法察覺。
繼承
模板中繼承是一個很方便的機制。或者可以認爲繼承是在使用已經過嚴格測試的模板引擎吧。讓我們來看看當Smarty和Twig執行繼承的時候會有多少性能上的負載。
我們建立了一個父模板,它擁有500個塊(blocks)的子模板,每個子模板都繼承於上一個子模板,同時子模板中都有靜態的數據提供給父模板來調用。我們將通過模板引擎處理該繼承鏈條的執行。
Result:
|
Compiling |
Execution |
Smarty 3.1.1 |
1.329 seconds |
0.002 seconds |
Twig 1.2.0 |
2.641 seconds |
0.121 seconds |
Smarty快60倍以上。如果我們查看編譯後的代碼,會很容易明白還不止60倍。Smarty將整個模板的xx聯合起來放到一個大文件中存放起來,執行起來就如同並不存在嵌套一樣。也就是說,Smarty的xx機制計劃沒有任何的性能損失,Twig是小心地爲每個xx模板建立類文件,並在執行期間一個個地嵌入並執行。
總結
結論很清晰:Smarty比Twig要更快,僅在一次性編譯較大模板時耗費了更多的時間,但除此之外其他的操作均有更高的性能。
我們測試的環境是:奔騰雙核T4200 (2 GHz),3GB內存,PHP5.3版本。如果你想在自己電腦上進行上述的性能測試,你可以在本文的最後下載全部代碼。