参评的几款模板引擎为:

  • XMLTemplate(简称XT)
  • Velocity(简称VT)
  • CommonTemplate(简称CT)
  • FreeMarker(简称FT)
  • Smarty4j(简称ST)
  • 直接的java代码

性能评测考虑以下几个方面:变量输出/循环/分支,这三大类调用构成了普通模板80%以上的功能。 
测试方法为双层循环,输出的中间体是一个空的不执行任何操作的Writer类, 
尽可能的减少模板外的性能影响因素,基本的逻辑伪代码描述如下:

Java代码  
  1. for (int i = 0; i < outerTime; i++) {
  2. for (int j = 0; j < innerTime; j++) {
  3. testXMLTemplate();
  4. }
  5. for (int j = 0; j < innerTime; j++) {
  6. testVelocityTemplate();
  7. }
  8. for (int j = 0; j < innerTime; j++) {
  9. testCommonTemplate();
  10. }
  11. for (int j = 0; j < innerTime; j++) {
  12. testFreeMarker();
  13. }
  14. for (int j = 0; j < innerTime; j++) {
  15. testSmarty4j();
  16. }
  17. for (int j = 0; j < innerTime; j++) {
  18. testJavaCode();
  19. }
  20. }

第一步,测试循环输出ascii码表,各模板引擎文件为

XT:asciitable.xhtml

Java代码  
  1. <div xmlns:c="http://www.xidea.org/ns/template/core">
  2. <h1>${name}</h1>
  3. <table border="${border}">
  4. <tr>
  5. <th>&#160;</th>
  6. <c:for var="cell" items="${data}">
  7. <th>${cell}</th>
  8. </c:for>
  9. </tr>
  10. <c:for var="row" items="${data}">
  11. <tr>
  12. <th>${row}</th>
  13. <c:for var="cell" items="${data}">
  14. <td><c:out value="&amp;#x"/>${row}${cell};</td>
  15. </c:for>
  16. </tr>
  17. </c:for>
  18. </table>
  19. </div>

VT:asciitable.vm

Java代码  
  1. <div>
  2. <h1>${name}</h1>
  3. <table border="${border}">
  4. <tr>
  5. <th>&#160;</th>
  6. #foreach($cell in $data)
  7. <th>${cell}</th>
  8. #end
  9. </tr>
  10. #foreach($row in $data)
  11. <tr>
  12. <th>${row}</th>
  13. #foreach($cell in $data )
  14. <td>&#x${row}${cell};</td>
  15. #end
  16. </tr>
  17. #end
  18. </table>
  19. </div>

CT:asciitable.ct

Java代码  
  1. <div>
  2. <h1>${name}</h1>
  3. <table border="${border}">
  4. <tr>
  5. <th>&#160;</th>
  6. $for{cell:data}
  7. <th>${cell}</th>
  8. $end
  9. </tr>
  10. $for{row:data}
  11. <tr>
  12. <th>${row}</th>
  13. $for{cell:data}
  14. <td>&#x${row}${cell};</td>
  15. $end
  16. </tr>
  17. $end
  18. </table>
  19. </div>

FT:asciitable.ftl

Java代码  
  1. <div>
  2. <h1>${name}</h1>
  3. <table border="${border}">
  4. <tr>
  5. <th>&#160;</th>
  6. <#list data as cell>
  7. <th>${cell}</th>
  8. </#list>
  9. </tr>
  10. <#list data as row>
  11. <tr>
  12. <th>${row}</th>
  13. <#list data as cell>
  14. <td>&#x${row}${cell};</td>
  15. </#list>
  16. </tr>
  17. </#list>
  18. </table>
  19. </div>
Java代码  
  1. ST:asciitable.html
  2. <div>
  3. <h1>{$name}</h1>
  4. <table border="{$border}">
  5. <tr>
  6. <th>&#160;</th>
  7. {section loop=$data name="cell"}
  8. <th>{$cell}</th>
  9. {/section}
  10. </tr>
  11. {section loop=$data name="row"}
  12. <tr>
  13. <th>{$row}</th>
  14. {section loop=$data name="cell"}
  15. <td>&#x{$row}{$cell};</td>
  16. {/section}
  17. </tr>
  18. {/section}
  19. </table>
  20. </div>

JAVA:asciitable.java

Java代码  
  1. package org.jside.tt;
  2. import java.io.Writer;
  3. import java.util.List;
  4. import java.util.Map;
  5. public class asciitable implements ICode {
  6. @Override
  7. public void execute(Map<String, Object> context, Writer writer) throws Exception {
  8. List<String> data = (List<String>) context.get("data");
  9. String name = (String) context.get("name");
  10. String border = (String) context.get("border");
  11. writer.write("<div>\n<h1>");
  12. writer.write(name);
  13. writer.write("</h1>\n<table border=\"");
  14. writer.write(border);
  15. writer.write("\">\n\t<tr>\n\t\t<th> </th>\n");
  16. for (String cell : data) {
  17. writer.write("\t\t<th>");
  18. writer.write(cell);
  19. writer.write("</th>\n");
  20. }
  21. writer.write("\t</tr>\n");
  22. for (String row : data) {
  23. writer.write("\t<tr>\n<th>");
  24. writer.write(row);
  25. writer.write("</th>\n");
  26. for (String cell : data) {
  27. writer.write("\t\t<td>&#x");
  28. writer.write(row);
  29. writer.write(cell);
  30. writer.write("</td>\n");
  31. }
  32. writer.write("\t</tr>\n");
  33. }
  34. writer.write("</table>\n</div>\n");
  35. }
  36. }

在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:

=============runing time===============

引用
xt:2149 
vt:3499 
ct:72254 
ft:2761 
st:1235 
CODE:1321

第二步,在最内层的循环中多输出一个对象,测试新增输出时的性能影响,最内层的那一行改造如下:

Java代码  
  1. XT:
  2. <td>${name}:<c:out value="&amp;#x"/>${row}${cell};</td>
  3. VT:
  4. <td>${name}:&#x${row}${cell};</td>
  5. CT:
  6. <td>${name}:&#x${row}${cell};</td>
  7. FT:
  8. <td>${name}:&#x${row}${cell};</td>
  9. ST:
  10. <td>{$name}:&#x{$row}{$cell};</td>
  11. JAVA:
  12. writer.write("\t\t<td>");
  13. writer.write(name);
  14. writer.write(":&#x");
  15. writer.write(row);
  16. writer.write(cell);
  17. writer.write("</td>\n");

在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是: 
=============runing time===============

引用
xt:3549 
vt:4748 
ct:103453 
ft:4251 
st:1750 
CODE:1811

第三步,测试分支判断对整体性能的影响,在最内层的循环中输出前加一个分支控制,使它仅输出A-Z对应的ASCII码表,改造如下:

Java代码  
  1. XT:
  2. <td><c:if test="${(row=='4' &amp;&amp; cell!='0') || (row=='5' &amp;&amp; cell&lt;'B')}"><c:out value="&amp;#x"/>${row}${cell};</c:if><c:else><c:out value="&amp;"/>nbsp;</c:else></td>
  3. VT:
  4. <td>#if(($row=="4" && $cell!="0") || ($row=="5" && $cell!="B" && $cell!="C" && $cell!="D" && $cell!="E" && $cell!="F"))&#x${row}${cell};#else&nbsp;#end</td>
  5. CT:
  6. <td>$if{(row=="4" && cell!="0") || (row=="5" && cell<"B")}&#x${row}${cell};$else{}&nbsp;$end</td>
  7. FT:
  8. <td><#if (row?string=="4" && cell?string!="0") || (row?string=='5' && cell?string!='B' && cell?string!='C' && cell?string!='D' && cell?string!='E' && cell?string!='F')>&#x${row}${cell};<#else>&nbsp;</#if></td>
  9. ST:
  10. <td>{if ($row==='4' && $cell!=='0') || ($row==='5' && $cell<'B')}&#x{$row}{$cell};{else}&nbsp;{/if}</td>
  11. JAVA:
  12. writer.write("\t\t<td>");
  13. if ((row.equals("4") && !cell.equals("0"))
  14. || (row.equals("5") && cell.compareTo("B") < 0)) {
  15. writer.write("&#x");
  16. writer.write(row);
  17. writer.write(cell);
  18. } else {
  19. writer.write("&nbsp;");
  20. }
  21. writer.write("</td>\n");

考虑到比较的问题,也可以对整个循环进行优化

Java代码  
  1. for (String row : data) {
  2. char cRow = row.charAt(0);
  3. writer.write("\t<tr>\n<th>");
  4. writer.write(row);
  5. writer.write("</th>\n");
  6. for (String cell : data) {
  7. char cCell = cell.charAt(0);
  8. writer.write("\t\t<td>");
  9. if ((cRow == '4' && cCell != '0') || (cRow == '5' && cCell < 'B')) {
  10. writer.write("&#x");
  11. writer.write(row);
  12. writer.write(cell);
  13. } else {
  14. writer.write("&nbsp;");
  15. }
  16. writer.write("</td>\n");
  17. }
  18. writer.write("\t</tr>\n");
  19. }

在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:

=============runing time===============

引用
xt:3498 
vt:2422 
ct:153280 
ft:7124 
st:1142 
CODE:1027(优化后940)

结论:  
ST在三种常见的模板操作中的表现均极其优秀,除了条件处理效率略低于直接书写的JAVA代码,其它情况下与直接书写JAVA代码效率完全一致,而且在三种操作中,总的执行开销差异非常小。 
XT在分支的处理中考虑与JS兼容带来了额外开销,但总体性能仍然占优,只是如果需要过多的XML转义可能影响阅读 
FT在分支测试中表现差的原因应该是写法不是最优的,总体来说,性能与VT不相上下 
CT的表现最差,在各项操作中均比其它的引擎慢了1-2个数量级

几款模板引擎的性能对比相关推荐

  1. python开发的系统有哪些_Python web开发=几个模板系统的性能对比

    Python web 开发:几个模板系统的性能对比 对比目标, jinja2 , cheetah , mako , webpy , bottle , tornado , django 的性能. 方法, ...

  2. 目前游戏行业内部主要几款游戏引擎的技术对比(转)

    如果只有客户端的话,可以考虑用gamebryo,技术好一点,用ogre也可以,如果规模不大,用unity3d,如果很有钱,要效果很好的,用unreal3,bigworld是带服务器的,如果能力不够,最 ...

  3. [转]目前游戏行业内部主要几款游戏引擎的技术对比

    如果只有客户端的话,可以考虑用gamebryo,技术好一点,用ogre也可以,如果规模不大,用unity3d,如果很有钱,要效果很好的,用unreal3,bigworld是带服务器的,如果能力不够,最 ...

  4. java fel_Java表达式引擎fel/groovy/expression4j/java脚本引擎的性能对比【原创】

    又是性能对比,最近跟性能较上劲了. 产品中需要用到数学表达式,表达式不复杂,但是对性能要求比较高.选用了一些常用的表达式引擎计算方案,包含:java脚本引擎(javax/script).groovy脚 ...

  5. 前端模板引擎artTemplate---高性能JavaScript模板引擎

    关于artTemplate模板引擎的详细原理请移步高性能JavaScript模板引擎原理解析,本文只探讨如何使用.初学前端的人一般对于绑定数据都是使用原生js或者jquery来拼接字符串,此为hard ...

  6. asp.net python 开发web 效率_【Django】Python web开发:几个模板系统的性能对比(转)...

    http://blog.chedushi.com/archives/910 结论: 点评一下吧.django就是个渣,不多废话了.webpy的代码很简洁,可惜速度太慢了.bottle看起来快一点,不过 ...

  7. 【JavsScript】推荐五款流行的JavaScript模板引擎

    摘要:Javascript模板引擎作为数据与界面分离工作中最重要一环,受到开发者广泛关注.本文通过开发实例解析五款流行模板引擎:Mustache.Underscore Templates.Embedd ...

  8. SpringBoot (三) :SpringBoot使用Freemarker模板引擎渲染web视图

    什么是Freemarker FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具. 它不是面向最终用户的,而 ...

  9. Java Mail+Thymeleaf模板引擎实现发送HTML格式邮件

    Java Mail+Thymeleaf模板引擎实现发送HTML格式邮件 基于Spring boot 1.5,Spring boot 2.x请使用Spring boot mail 1.依赖坐标 // b ...

最新文章

  1. 硬盘盘符双击无法打开,只能右键打开(解决方法)(转载)
  2. Jürgen Schmidhuber眼中的深度学习十年,以及下一个十年展望
  3. gradle build running很慢
  4. 字符驱动之按键(一:无脑轮询法)
  5. java ctp行情_java-ctp
  6. 马蜂窝数据仓库设计与实践
  7. nginx连接uwsgi使用web.py框架构造pythonweb项目
  8. DevOps是什么意思
  9. 微信自动抢红包软件被判赔475万
  10. Computer Systems A Programmer's Perspective(深入理解计算机系统)第一章读书笔记
  11. 开课吧Java课堂:如何运用equals( )和 equalsIgnoreCase( )
  12. You must install libks to build mod_signalwire
  13. 基于OpenCV 的图像分割
  14. RHEL7配置中文输入法-智能拼音
  15. 2048游戏英雄榜java_2048技巧 2048游戏排行榜挑战方法攻略详解
  16. 计算机网络谢希仁第七版课后习题答案(第三章)
  17. 实验二:MCMC训练的深度学习
  18. 云计算学习1——OpenStack云计算安装部署步骤图文并茂(先电2.2)
  19. 什么是JSP引擎?什么是JSP容器?什么是Web服务器?
  20. 【MarkDown使用技巧】轻松搞定MarkDown

热门文章

  1. ChatGPT的出圈与大佬们的焦虑
  2. 艾司博讯:拼多多回复率低于90会隐形降权么
  3. minecraft java_Minecraft Java版 1.13发布
  4. python多线程爬取多个网址_【Python爬虫】多线程爬取斗图网站(皮皮虾,我们上车)...
  5. 百度Ueditor 富文本弹出层,如何保证点击空白处不关闭
  6. TypeError: string indices must be integers
  7. 华为AR-1200-S 路由器拨号上网不能正常访问网页的问题解决
  8. python项目实战(一):购物商城(采用面向过程思想开发)
  9. 闲鱼python_python生成最小树
  10. Multiple comparison