百度有個VUI模塊,它負責將全部的廣告信息縇染成HTML返回給調用方,它採用的是HHVM,縇染模板用的是smarty,前端服務器用的是nginx。php
此前知道,新浪微博之前也用的是smarty,自從鳥哥過去後,將smarty所有換成原生的php模板,由於聽說性能提升了很多。前端
耳聽爲虛,眼見爲實,下面從各方面來分析一下smarty對咱們的性能產生多少影響。nginx
先貼下個人實驗環境,我對HHVM不太瞭解,先用官方的PHP進行實驗(php-fpm),nginx開了8個進程,php-fpm開了20個進程,23核CPU。apache
PHP代碼分有smarty和無smarty兩種,都僅有實驗代碼,沒有用別的框架。代碼中的邏輯採用smarty給的demo(一部分),我用原生的PHP重寫了一遍。代碼可下載。服務器
有smarty代碼的入口文件爲./demo/index.php,沒有smarty的入口文件爲./demo/nosmarty/index.php併發
我在代碼中加了函數執行時間統計,目的爲了獲取縇染模板的部分代碼執行的時間。框架
用apache的ab命令進行壓力測試,併發10個,不算大;同時用sar命令進行cpu利用率的統計。命令以下:函數
./ab -c 10 -n 100000 http://cq01-rdqa-dev072.cq01.baidu.com:8008/index.php
sar -u 2 1000 >/tmp/smarty.sar &
cpu利用率每2秒統計一次,獲取了71行數據,平均之後,CPU idle = 66.2845%,也就是平均CPU利用率爲32.8%php-fpm
收集到了123463條執行時間日誌,平均執行時間爲0.0100512秒。性能
ab命令顯示的Requests per second: 698.30 [#/sec] (mean)
cpu利用率每2秒統計一次,獲取了21行數據,平均之後,CPU idle = 90.9819%,也就是平均CPU利用率爲9.1%
收集到了100000條執行時間日誌,平均執行時間爲0.000179849秒。
ab命令顯示的Requests per second: 2326.84 [#/sec] (mean)
結論:在用smarty的狀況下,性能退化仍是比較明顯的,特別是CPU利用率比較高。
PHP原生模板也有很強大的功能,且不用從新學習模板語法,由於它就是PHP語言,因此還具備最高的靈活性。
進一步分析:
咱們能夠用strace -p PID attach到一個PHP-FPM進程,看看smarty到底多幹了些啥。
經過對比,咱們能夠發現有smarty時,會多出一些系統調用,其中片斷以下所示,這種片斷有10個左右,目的都是加載smarty的源代碼文件。
lstat("/home/users/huangxuan01/smartytest/demo/../libs/Smarty.class.php", {st_mode=S_IFREG|0664, st_size=48423, ...}) = 0 lstat("/home/users/huangxuan01/smartytest/demo/../libs", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 open("/home/users/huangxuan01/smartytest/libs/Smarty.class.php", O_RDONLY) = 4 fstat(4, {st_mode=S_IFREG|0664, st_size=48423, ...}) = 0 fstat(4, {st_mode=S_IFREG|0664, st_size=48423, ...}) = 0 fstat(4, {st_mode=S_IFREG|0664, st_size=48423, ...}) = 0 mmap(NULL, 48423, PROT_READ, MAP_SHARED, 4, 0) = 0x7fd328401000 mmap(NULL, 266240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd328281000 munmap(0x7fd328401000, 48423) = 0 close(4) =
咱們能夠繼續追一下它加載了哪些smarty文件,共有多少行。
23 /home/users/huangxuan01/smartytest/demo/index.php 1680 /home/users/huangxuan01/smartytest/libs/Smarty.class.php 576 /home/users/huangxuan01/smartytest/libs/sysplugins/smarty_internal_data.php 860 /home/users/huangxuan01/smartytest/libs/sysplugins/smarty_internal_templatebase.php 738 /home/users/huangxuan01/smartytest/libs/sysplugins/smarty_internal_template.php 912 /home/users/huangxuan01/smartytest/libs/sysplugins/smarty_resource.php 89 /home/users/huangxuan01/smartytest/libs/sysplugins/smarty_internal_resource_file.php 442 /home/users/huangxuan01/smartytest/libs/sysplugins/smarty_cacheresource.php 297 /home/users/huangxuan01/smartytest/libs/sysplugins/smarty_internal_cacheresource_file.php 98 /home/users/huangxuan01/smartytest/demo/templates_c/cd441ef1a05f578db0423976d6763729fd828a51.file.index.tpl.php 65 /home/users/huangxuan01/smartytest/libs/plugins/modifier.date_format.php 43 /home/users/huangxuan01/smartytest/libs/plugins/shared.make_timestamp.php 5823 total
發現它多加載了5823行代碼,我想這應該就是它性能比較差的緣由吧。在PHP這種解釋型語言中,多一行代碼就意味着多執行一段程序。