几款模板引擎的性能对比
来源:互联网 发布:手办买卖吧淘宝店铺 编辑:程序博客网 时间:2024/05/21 22:54
参评的几款模板引擎为:
性能评测考虑以下几个方面:变量输出/循环/分支,这三大类调用构成了普通模板80%以上的功能。
测试方法为双层循环,输出的中间体是一个空的不执行任何操作的Writer类,
尽可能的减少模板外的性能影响因素,基本的逻辑伪代码描述如下:
第一步,测试循环输出ascii码表,各模板引擎文件为
XT:asciitable.xhtml
VT:asciitable.vm
CT:asciitable.ct
FT:asciitable.ftl
JAVA:asciitable.java
在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:
=============runing time===============
第二步,在最内层的循环中多输出一个对象,测试新增输出时的性能影响,最内层的那一行改造如下:
在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:
=============runing time===============
第三步,测试分支判断对整体性能的影响,在最内层的循环中输出前加一个分支控制,使它仅输出A-Z对应的ASCII码表,改造如下:
考虑到比较的问题,也可以对整个循环进行优化
在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:
=============runing time===============
结论:
ST在三种常见的模板操作中的表现均极其优秀,除了条件处理效率略低于直接书写的JAVA代码,其它情况下与直接书写JAVA代码效率完全一致,而且在三种操作中,总的执行开销差异非常小。
XT在分支的处理中考虑与JS兼容带来了额外开销,但总体性能仍然占优,只是如果需要过多的XML转义可能影响阅读
FT在分支测试中表现差的原因应该是写法不是最优的,总体来说,性能与VT不相上下
CT的表现最差,在各项操作中均比其它的引擎慢了1-2个数量级
- XMLTemplate(简称XT)
- Velocity(简称VT)
- CommonTemplate(简称CT)
- FreeMarker(简称FT)
- Smarty4j(简称ST)
- 直接的java代码
性能评测考虑以下几个方面:变量输出/循环/分支,这三大类调用构成了普通模板80%以上的功能。
测试方法为双层循环,输出的中间体是一个空的不执行任何操作的Writer类,
尽可能的减少模板外的性能影响因素,基本的逻辑伪代码描述如下:
- for (int i = 0; i < outerTime; i++) {
- for (int j = 0; j < innerTime; j++) {
- testXMLTemplate();
- }
- for (int j = 0; j < innerTime; j++) {
- testVelocityTemplate();
- }
- for (int j = 0; j < innerTime; j++) {
- testCommonTemplate();
- }
- for (int j = 0; j < innerTime; j++) {
- testFreeMarker();
- }
- for (int j = 0; j < innerTime; j++) {
- testSmarty4j();
- }
- for (int j = 0; j < innerTime; j++) {
- testJavaCode();
- }
- }
第一步,测试循环输出ascii码表,各模板引擎文件为
XT:asciitable.xhtml
- <div xmlns:c="http://www.xidea.org/ns/template/core">
- <h1>${name}</h1>
- <table border="${border}">
- <tr>
- <th> </th>
- <c:for var="cell" items="${data}">
- <th>${cell}</th>
- </c:for>
- </tr>
- <c:for var="row" items="${data}">
- <tr>
- <th>${row}</th>
- <c:for var="cell" items="${data}">
- <td><c:out value="&#x"/>${row}${cell};</td>
- </c:for>
- </tr>
- </c:for>
- </table>
- </div>
VT:asciitable.vm
- <div>
- <h1>${name}</h1>
- <table border="${border}">
- <tr>
- <th> </th>
- #foreach($cell in $data)
- <th>${cell}</th>
- #end
- </tr>
- #foreach($row in $data)
- <tr>
- <th>${row}</th>
- #foreach($cell in $data )
- <td>&#x${row}${cell};</td>
- #end
- </tr>
- #end
- </table>
- </div>
CT:asciitable.ct
- <div>
- <h1>${name}</h1>
- <table border="${border}">
- <tr>
- <th> </th>
- $for{cell:data}
- <th>${cell}</th>
- $end
- </tr>
- $for{row:data}
- <tr>
- <th>${row}</th>
- $for{cell:data}
- <td>&#x${row}${cell};</td>
- $end
- </tr>
- $end
- </table>
- </div>
FT:asciitable.ftl
- <div>
- <h1>${name}</h1>
- <table border="${border}">
- <tr>
- <th> </th>
- <#list data as cell>
- <th>${cell}</th>
- </#list>
- </tr>
- <#list data as row>
- <tr>
- <th>${row}</th>
- <#list data as cell>
- <td>&#x${row}${cell};</td>
- </#list>
- </tr>
- </#list>
- </table>
- </div>
- ST:asciitable.html
- <div>
- <h1>{$name}</h1>
- <table border="{$border}">
- <tr>
- <th> </th>
- {section loop=$data name="cell"}
- <th>{$cell}</th>
- {/section}
- </tr>
- {section loop=$data name="row"}
- <tr>
- <th>{$row}</th>
- {section loop=$data name="cell"}
- <td>&#x{$row}{$cell};</td>
- {/section}
- </tr>
- {/section}
- </table>
- </div>
JAVA:asciitable.java
- package org.jside.tt;
- import java.io.Writer;
- import java.util.List;
- import java.util.Map;
- public class asciitable implements ICode {
- @Override
- public void execute(Map<String, Object> context, Writer writer) throws Exception {
- List<String> data = (List<String>) context.get("data");
- String name = (String) context.get("name");
- String border = (String) context.get("border");
- writer.write("<div>\n<h1>");
- writer.write(name);
- writer.write("</h1>\n<table border=\"");
- writer.write(border);
- writer.write("\">\n\t<tr>\n\t\t<th> </th>\n");
- for (String cell : data) {
- writer.write("\t\t<th>");
- writer.write(cell);
- writer.write("</th>\n");
- }
- writer.write("\t</tr>\n");
- for (String row : data) {
- writer.write("\t<tr>\n<th>");
- writer.write(row);
- writer.write("</th>\n");
- for (String cell : data) {
- writer.write("\t\t<td>&#x");
- writer.write(row);
- writer.write(cell);
- writer.write("</td>\n");
- }
- writer.write("\t</tr>\n");
- }
- writer.write("</table>\n</div>\n");
- }
- }
在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:
=============runing time===============
引用
xt:2149
vt:3499
ct:72254
ft:2761
st:1235
CODE:1321
vt:3499
ct:72254
ft:2761
st:1235
CODE:1321
第二步,在最内层的循环中多输出一个对象,测试新增输出时的性能影响,最内层的那一行改造如下:
- XT:
- <td>${name}:<c:out value="&#x"/>${row}${cell};</td>
- VT:
- <td>${name}:&#x${row}${cell};</td>
- CT:
- <td>${name}:&#x${row}${cell};</td>
- FT:
- <td>${name}:&#x${row}${cell};</td>
- ST:
- <td>{$name}:&#x{$row}{$cell};</td>
- JAVA:
- writer.write("\t\t<td>");
- writer.write(name);
- writer.write(":&#x");
- writer.write(row);
- writer.write(cell);
- writer.write("</td>\n");
在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:
=============runing time===============
引用
xt:3549
vt:4748
ct:103453
ft:4251
st:1750
CODE:1811
vt:4748
ct:103453
ft:4251
st:1750
CODE:1811
第三步,测试分支判断对整体性能的影响,在最内层的循环中输出前加一个分支控制,使它仅输出A-Z对应的ASCII码表,改造如下:
- XT:
- <td><c:if test="${(row=='4' && cell!='0') || (row=='5' && cell<'B')}"><c:out value="&#x"/>${row}${cell};</c:if><c:else><c:out value="&"/>nbsp;</c:else></td>
- VT:
- <td>#if(($row=="4" && $cell!="0") || ($row=="5" && $cell!="B" && $cell!="C" && $cell!="D" && $cell!="E" && $cell!="F"))&#x${row}${cell};#else #end</td>
- CT:
- <td>$if{(row=="4" && cell!="0") || (row=="5" && cell<"B")}&#x${row}${cell};$else{} $end</td>
- FT:
- <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> </#if></td>
- ST:
- <td>{if ($row==='4' && $cell!=='0') || ($row==='5' && $cell<'B')}&#x{$row}{$cell};{else} {/if}</td>
- JAVA:
- writer.write("\t\t<td>");
- if ((row.equals("4") && !cell.equals("0"))
- || (row.equals("5") && cell.compareTo("B") < 0)) {
- writer.write("&#x");
- writer.write(row);
- writer.write(cell);
- } else {
- writer.write(" ");
- }
- writer.write("</td>\n");
考虑到比较的问题,也可以对整个循环进行优化
- for (String row : data) {
- char cRow = row.charAt(0);
- writer.write("\t<tr>\n<th>");
- writer.write(row);
- writer.write("</th>\n");
- for (String cell : data) {
- char cCell = cell.charAt(0);
- writer.write("\t\t<td>");
- if ((cRow == '4' && cCell != '0') || (cRow == '5' && cCell < 'B')) {
- writer.write("&#x");
- writer.write(row);
- writer.write(cell);
- } else {
- writer.write(" ");
- }
- writer.write("</td>\n");
- }
- writer.write("\t</tr>\n");
- }
在outerTime=100与innerTime=100时,共循环10000次,平均的结果约是:
=============runing time===============
引用
xt:3498
vt:2422
ct:153280
ft:7124
st:1142
CODE:1027(优化后940)
vt:2422
ct:153280
ft:7124
st:1142
CODE:1027(优化后940)
结论:
ST在三种常见的模板操作中的表现均极其优秀,除了条件处理效率略低于直接书写的JAVA代码,其它情况下与直接书写JAVA代码效率完全一致,而且在三种操作中,总的执行开销差异非常小。
XT在分支的处理中考虑与JS兼容带来了额外开销,但总体性能仍然占优,只是如果需要过多的XML转义可能影响阅读
FT在分支测试中表现差的原因应该是写法不是最优的,总体来说,性能与VT不相上下
CT的表现最差,在各项操作中均比其它的引擎慢了1-2个数量级
0 0
- 几款模板引擎的性能对比
- 主题:几款模板引擎的性能对比
- 几款Java模板引擎的性能评测
- 对几种流行的Javascript模板引擎的测试对比
- 各种JS模板引擎对比数据(高性能JavaScript模板引擎)
- 各种JS模板引擎对比数据(高性能JavaScript模板引擎)
- 各种JS模板引擎对比数据(高性能JavaScript模板引擎)
- 各种JS模板引擎对比数据(高性能JavaScript模板引擎)
- 几款流行Flash3D引擎对比介绍
- 几款游戏引擎技术对比
- Java几款性能分析工具的对比
- Java几款性能分析工具的对比
- Java几款性能分析工具的对比
- Java几款性能分析工具的对比
- Java几款性能分析工具的对比
- Java几款性能分析工具的对比
- Java几款性能分析工具的对比
- Java几款性能分析工具的对比
- ANDROID STUDIO系列教程二--基本设置与运行
- python MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") TypeError: __call__() takes exactly 2
- JavaScript之DOM详细使用实例
- 浅析Android Camera开发中的三个尺寸和三种变形 (贡献一个自适配Picturesize和Previewsize的工具类)
- TCP/IP详解学习笔记(5)-IP选路,动态选路,和一些细节
- 几款模板引擎的性能对比
- Find Mode in Binary Search Tree
- shell基础学习
- TCP/IP详解学习笔记(6)-UDP协议
- SQL建立索引
- salesforce标准对象(2)
- 根据价格变化自动识别极值点策略
- String与NSString关系
- java RMI原理详解