锁定老帖子 主题:比Velocity快10倍的模板引擎
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-09-14
我现在喜欢用StringTemplate了。
|
|
返回顶楼 | |
发表时间:2011-09-14
javatar 写道 bao231 写道 感觉楼主应该说一下httl为什么比其他的快这么多,做了哪些技术优化,像温少一样,有个技术内幕之类的东西。这样才能有人用,否则大家都是一团雾水撒,谁还敢用呢,期待
![]() 说白了,就只是将模板转成Java源码,再将Java源码生成字节码,因JDK生成字节码的效率高,另外,基于强类型编译和类型推演,减少了运行时反射和判断,没什么太多内幕,看源代码就知道了,后面有空再补几个设计文档。 那为啥不用jsp标签呢? |
|
返回顶楼 | |
发表时间:2011-09-14
sslaowan 写道 javatar 写道 bao231 写道 感觉楼主应该说一下httl为什么比其他的快这么多,做了哪些技术优化,像温少一样,有个技术内幕之类的东西。这样才能有人用,否则大家都是一团雾水撒,谁还敢用呢,期待
![]() 说白了,就只是将模板转成Java源码,再将Java源码生成字节码,因JDK生成字节码的效率高,另外,基于强类型编译和类型推演,减少了运行时反射和判断,没什么太多内幕,看源代码就知道了,后面有空再补几个设计文档。 那为啥不用jsp标签呢? JSP的标签有Tag扩展点(JSTL是基于Tag扩展点的),实际上是解释执行的,EL也是解释执行,而且在编译期不知道参数类型,不能在编译期推演变量类型,在解释时会慢一些。 |
|
返回顶楼 | |
发表时间:2011-09-14
html混一起的语法确实很纠结。。。
|
|
返回顶楼 | |
发表时间:2011-09-14
以下 是我过去测试的结果。有一年多了。
说明:多线程,交叉模板环境测试。 本测试没有使用io。 Freemaker 稳定,快,但不好扩展,语法非标准XML CommonTemplate:速度和稳定行的欠佳,多线程下容易错误,特点支持语法套。 velocity: 运行很快, 多线程下容易错误,最快的是他,最容易出错的也是它。语法本人不喜欢。 smarty4j:单线程最快,多线程最慢的一个,稳定。 切点并发能力低。 ScriptMark:在高压的时候约有优势,低压反而要弱一些,总体和Freemaker差不多,特点扩展方便,标准的XML。(http://code.google.com/p/jspxnet/downloads/list) |
|
返回顶楼 | |
发表时间:2011-09-14
最好向前兼容一下以前的语法吧,哪怕是一部分,
或者有个靠谱的工具和方案能把原来的ctl语法转成现在的语法, 让以前的使用者 重树信心 比一些新奇的语法来的更重要些吧,既然有方法也有热情, 我一度很支持国产开源,在很多项目中采用多个开源项目,但是国产开源真的不支持我们这些对其寄予希望的使用者,用到最后就变成了,提了问题很久没人处理,只能自已check源代码,自己修改其中的错误, 虽然做为开源项目的发起者真的没有义务对我们使用者的选择造成结果负责,但是如果只是为了炫技的话,真的不要再做另一个虎头蛇尾的“ctl项目”了, |
|
返回顶楼 | |
发表时间:2011-09-14
最后修改:2011-09-14
heaven 写道 最好向前兼容一下以前的语法吧,哪怕是一部分,
或者有个靠谱的工具和方案能把原来的ctl语法转成现在的语法, 让以前的使用者 重树信心 比一些新奇的语法来的更重要些吧,既然有方法也有热情, 我一度很支持国产开源,在很多项目中采用多个开源项目,但是国产开源真的不支持我们这些对其寄予希望的使用者,用到最后就变成了,提了问题很久没人处理,只能自已check源代码,自己修改其中的错误, 虽然做为开源项目的发起者真的没有义务对我们使用者的选择造成结果负责,但是如果只是为了炫技的话,真的不要再做另一个虎头蛇尾的“ctl项目”了, OK,后续会考虑兼容以前的语法,其实现在的语法就是以前ctl的属性语法外套。 |
|
返回顶楼 | |
发表时间:2011-09-14
高手出马,立马见真章哈。貌似实现的思路和simpleEL有点类似,生成java源代码字节流,通过java compiler tool进行动态编译成class进行使用。
还有我对LZ的几个优化实现比较感兴趣,能否详细介绍下? 引用 (3) 减少int到Integer等元类型的boxed和unboxed,以及instanceof。
因为模板输出的大量是基本类型和字符串, 比如当输出基本类型时,需要转成String,如果使用format(Object)接口,就会将基本类型装箱, Httl遇到任何类似需要boxed和unboxed的地方,都会重载所有基本类型方法,以减少boxed和unboxed的处理。 出现instanceof的地方也一样,会转为重复字节码多态处理。 你这里说是减少boxed/unboxed的处理,主要是体现在哪个方面?默认都转化成对象处理吗? instanceof的处理,处理过后最后的生成的字节码会是怎么样?好奇一下,invokevirtual ? 引用 6) 对同条件if语句优化:(未发布)
Java代码 if (user.role == "admin") { // ... } else if (user.role == "member") { // ... } else { // ... } if (user.role == "admin") { // ... } else if (user.role == "member") { // ... } else { // ... } 优化后: Java代码 int id = System.identityHashCode(user.role); switch (id) { case 3452345: // 编译时计算"admin"的identityHashCode // ... case 2342452: // 编译时计算"member"的identityHashCode // ... default: // ... } int id = System.identityHashCode(user.role); switch (id) { case 3452345: // 编译时计算"admin"的identityHashCode // ... case 2342452: // 编译时计算"member"的identityHashCode // ... default: // ... } 一直没搞清楚if语句和case语句性能上的差异点在哪?LZ帮忙解释下吧 引用 (5) 对大模板拆分子函数:(未发布)
SunJDK缺省对大于5K字节码的方法不进行JIT优化, 所以当模板的内容较大时,会导致生成的字节码也比较大, 通过拆分子函数,可以解决JIT优化问题。 如果这个也是实现了的话,那真当做到极致了。不过也有点好奇你的实现思路?怎么识别可以拆分为子函数,语法解析? |
|
返回顶楼 | |
发表时间:2011-09-14
javatar 写道 sures 写道 支持楼主,除了保证速度,功能上也希望能胜过Velocity。最终还是功能取胜!
HTTL的各功能都可扩展和替换,就算就换语法也是可行的,所以后面会考虑同时解析Velocity语法。 另外,对于工具方法的扩展,HTTL比Velocity更直观,比如: public class StringUtil { public static String escape(String value) { // ... } } (1) Velocity: 先配置tools扩展: <toolbox> <tool> <key>stringUtil</key> <scope>application</scope> <class>com.xxx.StringUtil</class> </tool> </toolbox> 然后当工具方法使用: $stringUtil.escape($content) (2) Httl: 先在httl.properties配置: functions=+com.xxx.StringUtil 然后直接把StringUtil中的静态函数,当String的属性用:(语法上更面向对象) $content.escape 基于静态方法的第一个参数类型识别,而且是编译期识别,直接将静态调用转成了字节码,不会影响性能。 这个Httl的工具类支持怎么看着有点别扭 如果是基于参数识别,那如果我注册的两个工具类有着相同的参数。那Httl会是如何处理? 根据变量类型找到方法执行,这个我觉得有点优化过度了,反而不太符合一般人的编程习惯 |
|
返回顶楼 | |
发表时间:2011-09-14
最后修改:2011-09-14
agapple 写道 你这里说是减少boxed/unboxed的处理,主要是体现在哪个方面?默认都转化成对象处理吗?
一般的模板引擎都将数字boxed成Object再处理,因为要反射,而模板上大量使用基本类型输出,优化是有意义的。 agapple 写道 一直没搞清楚if语句和case语句性能上的差异点在哪?LZ帮忙解释下吧
Java的字节码中if语句实现上是编译成JUMP和GOTO语句的,而switch是编译成偏量表的,一次偏移到位,不用一次次检测,所以switch的case值只能是基本类型,而且不能是变量。 agapple 写道 怎么识别可以拆分为子函数,语法解析?
HTTL本来就要解析模板,因为要推断所有变量的类型,转换语句的语法为Java语法,所以在解析的过程中,判断一个文本的长度是否过大,如果过大就转成两个函数,相互调用。 |
|
返回顶楼 | |