剖析 「‘最好的模板引擎’Beetl剖析及與Tiny模板引擎對比」

    http://blog.csdn.net/cndes/art ... 88771 這有一篇文章,說是剖析beetl模板引擎,並與同爲國內的tiny模板引擎作對比(如下簡稱「剖析beetl」),其剖析過程公正,但結論卻不正確(文中暗示的結論,而不是文章最後一段總結),

   每次在百度裏搜索beetl,這篇文章總會出現,也有打算使用beetl的人會將信將疑的把這文章發給我看以求證裏面剖析是否正確。在beetl社區解釋都比較費口舌,所以決定寫一篇文章說明一下我觀點。

    那篇剖析文章太長,惟一上代碼的地方就是beetl的 for循環實現源碼,做者也拿出tiny 模板引擎的循環實現源碼,來證實「tiny短小精悍,功能豐富,然而那個做者弄錯了。

   做者不清楚beetl的循環有一個重要功能,安全輸出,代碼以下(79行)java

// java 實現
if (collection == null)
    {
        if (!this.hasSafe)
        {
            BeetlException ex = new BeetlException(BeetlException.NULL);
            ex.pushToken(exp.token);
            throw ex;
        }
        else
        {
            it = new IteratorStatus(Collections.EMPTY_LIST);
        }

}
    也就是說在安全模式下,若是結果集爲空,則不會進入循環體,也不會拋錯。雖然多了6行代碼,卻多了一個安全輸出功能,beetl開發者只要用安全輸出符號! 就能夠了,以下beetl代碼
 
//beetl 代碼
var users = null;
for(u in users!){

}



    再回頭看看那beetl源碼,若是集合爲null,且沒有安全輸出,則會拋出一個BeetlException異常,說明是空值異常,而且 ex.pushToken(exp.token); 這個語句經過token指明瞭是哪一個符號出錯,
beetl的錯誤提示很是友好,這是衆所周知的,也在於它的代碼裏到處有主動的異常的處理,而不是被動拋出異常。

    而後咱們再看104行代碼

ctx.vars[varIndex + 1] = it; 這句代碼是將集合賦值到beetl變量表裏,一樣還要114行的賦值 ctx.vars[varIndex] = it.next(); 這種將值賦值給數組元素的方式,相似低級語言的指針,帶來的好處就是經過數組索引訪問變量,速度很是快,這在個人一篇博客裏說明過這個問題http://my.oschina.net/xiandafu/blog/293167,這篇博客說明,經過數組索引訪問變量,比傳統模板引擎使用的Map經過變量名來存取快100倍。
    固然實現這個爲變量分配索引(相似c語言的指針),用了大量的語法解析代碼,這也是beetl自己較大的緣由(然而遠小於freemarker和veclotiy),那篇剖析文章顯然沒有看到beetl的這個特性,而草率認爲beetl體積過大,「剖析beetl」也沒有看到beetl 對for循環的優化,由於for循環總要對跳出語句進行檢查(break;return;continue),所以,代碼看起來以下(115行)數組

forPart.execute(ctx);
switch (ctx.gotoFlag)
{
    case IGoto.NORMAL:
        break;
    case IGoto.CONTINUE:
        ctx.gotoFlag = IGoto.NORMAL;
        continue;
    case IGoto.RETURN:
        return;
    case IGoto.BREAK:
        ctx.gotoFlag = IGoto.NORMAL;
        return;
}



     但beetl也對於這種跳出作了優化,由於在語法解析階段,就能分析出循環是否含有跳出語句,若是沒有跳出語句,則沒必要執行跳出檢測,代碼在139行安全

// java實現
while (it.hasNext())
{
     ctx.vars[varIndex] = it.next();
     forPart.execute(ctx);

}



    代碼在109行先檢測是否含有跳出語句if (this.hasGoto),若是沒有,則直接執行如上循環

    最後,讓咱們再來看看beetl循環另一個特性,elsefor 語法,若是沒有進入循環體,則進入eslefor循環,以下beetl代碼性能

// beetl代碼
var users = null;
for(u in users!){

}elsefor{
print("no value");
}
    實現這個特性,beetl仍然用了"幾句冗長代碼"實現,代碼以下:
// java實現
if (!it.hasData())
        {
            if (elseforPart != null)
                elseforPart.execute(ctx);
        }
}



    經過it.hasData 判斷是否進入循環體,若是沒有,但模板具備elsefor,則執行elsefor部分邏輯。

    到此爲止,for循環實現的主體總共80餘行代碼自我剖析完畢,beetl裏面有安全輸出,有eslefor 特點語法,有跳出檢測以優化性能,還有高性能的變量管理,還有無處不在異常處理,做爲beetl做者,我並不以爲代碼還能精簡到什麼程度,若是你反觀"剖析beetl文章"裏提到的tiny template的循環實現源碼,你會問,安全輸出在哪裏?若是沒有進入循環體,我是否也有elsefor幫忙處理?還有,怎麼沒看到異常處理.以及跳出檢測和跳出優化?tiny template 的變量管理方式仍是map方式而不是速度更多的數組方式?

   相信你已經對「剖析beetl」這文章是否靠譜已經有了正確認識。同時市場也是檢驗真理的標準,我做爲獨立開發者(也有愛好者捐獻了beetl擴展),不買粉,不拉票,不巡講,沒有企業推手,經過5年的開發和維護,beetl事實上已經成爲國內最爲流行的java模板引擎之一,能代替長期壟斷的國外freemaker和velcoity。,這些市場成果也證實了「剖析beetl"是多麼的不靠譜和結論草率!優化

相關文章
相關標籤/搜索