文档章节

剖析 “‘最好的模板引擎’Beetl剖析及与Tiny模板引擎对比”

闲大赋
 闲大赋
发布于 2016/07/14 10:00
字数 1382
阅读 714
收藏 0

    http://blog.csdn.net/cndes/art ... 88771 这有一篇文章,说是剖析beetl模板引擎,并与同为国内的tiny模板引擎做对比(以下简称“剖析beetl”),其剖析过程公正,但结论却不正确(文中暗示的结论,而不是文章最后一段总结),

   每次在百度里搜索beetl,这篇文章总会出现,也有打算使用beetl的人会将信将疑的把这文章发给我看以求证里面剖析是否正确。在beetl社区解释都比较费口舌,因此决定写一篇文章说明一下我观点。

    那篇剖析文章太长,唯一上代码的地方就是beetl的 for循环实现源码,作者也拿出tiny 模板引擎的循环实现源码,来证明“tiny短小精悍,功能丰富,然而那个作者弄错了。

   作者不清楚beetl的循环有一个重要功能,安全输出,代码如下(79行)

// 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"是多么的不靠谱和结论草率!

 

© 著作权归作者所有

共有 人打赏支持
闲大赋

闲大赋

粉丝 1164
博文 95
码字总数 88056
作品 10
西城
架构师
私信 提问
加载中

评论(9)

l
lblin
不否认模板考虑的周到,但是对于使用者来说,最烦的一点是,模板语法在多种语言语法间的混搭,要么模板语法全部以java语法为基准,要么全部以js语法为基准,统一使用习惯才能更好的让使用者熟练。例如!语法,既然使用的是js语法基准,那么js中早就有var a = o | "default";这样的写法来 为null对象o提供一个默认值,为何作者非要增加一个不习惯的!字符来实现相同的功能,契合大家的语言习惯的工具不是更容易上手么
O龙猫O
O龙猫O
tiny在模板引擎上,确实下了很大功夫。
tiny模板引擎只是整个tiny框架的一部分,tiny的整个体系还是很庞大的。
tiny有一点不足,它是GPL协议的,这方面我认为比较限制它的发展。
ibeetl应该是MIT协议的,这点很友好。
根据我的了解,ibeetl,一开始就是做模板引擎的,然后推出了orm工具。
就技术而言,各有各的玩法,无所谓好坏,选一个适合自己的就好。
技术重在交流,同行不是冤家。有交流才有思想碰撞,才有进步。
蒲池幸子
蒲池幸子
支持beetl
等待美丽的花儿
等待美丽的花儿
说的好。支持
拐子
拐子
重度用户,顶一个
唐家V
唐家V
beetl为开发者提供了很多好用的功能,值得支持,加油。
引鸩怼孑
引鸩怼孑
加油!
e
eric_jfire
分析透彻。tiny文章作者断章取义,有误导用户之嫌。作为开源作者,作品竞争本是正常,但应该公证客观的说出观点并且给出证据,而不是使用带有误导性质的言语,片面的截取代码分析。在这点上,beetl作者是非常棒的。支持beetl
Gavin-King
Gavin-King
分析透彻,清晰!
悠然乱弹:“最好的模板引擎”Beetl 剖析及与Tiny模板引擎对比

Beetl的环境搭建 输入命令 git clone https://git.oschina.net/xiandafu/beetl2.0.git不一会儿,输出了下面的内容 Cloning into 'beetl2.0'...remote: Counting objects: 5807, done.remote:......

悠悠然然
2015/08/01
0
44
TinyTemplate模板引擎火热出炉,正式开源了~~~

涉水模板引擎领域,纯属不小心。 在此对以下人员表示强烈感谢与致敬: @sub jetbrick作者 @sept @webit webit作者 @罗格林 rythm作者 @闲.大赋 beetl作者 以及许许多多虽然没有列出来,但是在...

悠悠然然
2014/06/18
0
29
OSChina 开源周刊 46 期,每周技术精粹

每周技术抢先看,总有你想要的! 开源资讯 2015 年 Android 碎片化情况让人吃惊 OpenSSL 将改用 Apache 2.0 许可协议 开源中国 Maven 镜像库重新上线,天翼云提供支持 Windows 开源 iOS 到 ...

OSC编辑部
2015/08/07
3.5K
4
一种web编程的新的模板处理思路

目前web开发中充斥着各种各样的模板引擎,从前端到后端,性能优劣暂且不论,剖析其大体工作方式,可以概括为:实例化模板!也就是将Controller处理结果生产的Model数据通过模板引擎渲染View(...

hanzhankang
2013/11/07
0
4
第五章:视图技术之-Beetl模板引擎

1、特性介绍 功能完备:作为主流模板引擎,Beetl具有相当多的功能和其他模板引擎不具备的功能。适用于各种应用场景,从对响应速度有很高要求的大网站到功能繁多的CMS管理系统都适合。Beetl本...

刘祖鹏
05/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

对接比特币钱包的PHP开发包

BtcTool是一个基于第三方服务和离线裸交易实现的PHP比特币应用开发包,适合不希望部署本地 节点旳PHP开发者,开发包主要包含以下特性: 利用第三方服务获取指定地址的utxo集合 离线生成消费裸...

汇智网教程
1分钟前
0
0
【自用】 VHD to VHDX

VHDX: 在VHD 2TB 的基础上提供 64TB的容量。 支持逻辑扇区大小为 4KB,和每块的大小为 256MB,来优化虚拟磁盘性能。 比VHD提供更高的安全性、可靠性和性能。 convert-VHD –path d:\Hyper-v...

Tensor丨思悟
14分钟前
0
0
30 岁转行做Python开发晚吗?而且是零基础

最近有小伙伴问小编,30 岁转行做Python开发晚吗? 小编想说,其实无论男女,只要想学,有这个动力,就直接去行动。无论年龄,无论性别,只要你想一直勇往直前,那么想做的就去做吧~这里有一...

糖宝lsh
24分钟前
7
0
详解Spring中的Profile

前言 由于在项目中使用Maven打包部署的时候,经常由于配置参数过多(比如Nginx服务器的信息、ZooKeeper的信息、数据库连接、Redis服务器地址等),导致实际现网的配置参数与测试服务器参数混淆...

watermelon11
39分钟前
4
0
phper必知必会(二)

  1.说说你对进程,线程以及协程的理解      进程:是系统进行资源分配和调度的基本单位,是基本操作系统结构的基础。进程是程序基本执行的实体。进程与进程之间是独立的,拥有完全独立...

SEOwhywhy
55分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部