java模板引擎效率_几款Java模板引擎的性能评测

本文对比了XMLTemplate、Velocity等六种模板引擎在变量输出、循环和分支处理上的性能,并通过具体测试案例展示了不同引擎的特点及优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参评的几款模板引擎为:

XMLTemplate(简称XT)

Velocity(简称VT)

CommonTemplate(简称CT)

FreeMarker(简称FT)

Smarty4j(简称ST)

直接的java代码

以下所有测评的结果单位都是ms

性能评测考虑以下几个方面:变量输出/循环/分支,这三大类调用构成了普通模板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

${name}

 ${cell}
${row}${row}${cell};

VT:asciitable.vm

${name}

 

#foreach($cell in $data)

${cell}

#end

#foreach($row in $data)

${row}

#foreach($cell in $data )

${row}${cell};

#end

#end

CT:asciitable.ct

${name}

 

$for{cell:data}

${cell}

$end

$for{row:data}

${row}

$for{cell:data}

${row}${cell};

$end

$end

FT:asciitable.ftl

${name}

 ${cell}

#list>

${row}${row}${cell};

#list>

#list>

ST:asciitable.html

{$name}

 

{section loop=$data name="cell"}

{$cell}

{/section}

{section loop=$data name="row"}

{$row}

{section loop=$data name="cell"}

{$row}{$cell};

{/section}

{/section}

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 context, Writer writer) throws Exception {

List data = (List) context.get("data");

String name = (String) context.get("name");

String border = (String) context.get("border");

writer.write("

/n

");

writer.write(name);

writer.write("/n

writer.write(border);

writer.write("/">/n/t

/n/t/t /n");

for (String cell : data) {

writer.write("/t/t

");

writer.write(cell);

writer.write("

/n");

}

writer.write("/t

/n");

for (String row : data) {

writer.write("/t

/n");

writer.write(row);

writer.write("

/n");

for (String cell : data) {

writer.write("/t/t

");

writer.write(row);

writer.write(cell);

writer.write("

/n");

}

writer.write("/t

/n");

}

writer.write("

/n
/n");

}

}

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

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

xt:2149

vt:3499

ct:72254

ft:2761

st:1235

CODE:1321

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

XT:

${name}:${row}${cell};

VT:

${name}:${row}${cell};

CT:

${name}:${row}${cell};

FT:

${name}:${row}${cell};

ST:

{$name}:{$row}{$cell};

JAVA:

writer.write("/t/t

");

writer.write(name);

writer.write(":");

writer.write(row);

writer.write(cell);

writer.write("

/n");

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

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

xt:3549

vt:4748

ct:103453

ft:4251

st:1750

CODE:1811

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

XT:

${row}${cell};nbsp;

VT:

#if(($row=="4" && $cell!="0") || ($row=="5" && $cell!="B" && $cell!="C" && $cell!="D" && $cell!="E" && $cell!="F"))${row}${cell};#else #end

CT:

$if{(row=="4" && cell!="0") || (row=="5" && cell

FT:

${row}${cell}; #if>

ST:

{if ($row==='4' && $cell!=='0') || ($row==='5' && $cell

JAVA:

writer.write("/t/t

");

if ((row.equals("4") && !cell.equals("0"))

|| (row.equals("5") && cell.compareTo("B") < 0)) {

writer.write("");

writer.write(row);

writer.write(cell);

} else {

writer.write(" ");

}

writer.write("

/n");

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

for (String row : data) {

char cRow = row.charAt(0);

writer.write("/t

/n");

writer.write(row);

writer.write("

/n");

for (String cell : data) {

char cCell = cell.charAt(0);

writer.write("/t/t

");

if ((cRow == '4' && cCell != '0') || (cRow == '5' && cCell < 'B')) {

writer.write("");

writer.write(row);

writer.write(cell);

} else {

writer.write(" ");

}

writer.write("

/n");

}

writer.write("/t

/n");

}

在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个数量级

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值