抽空写了下对HTTL质量分析的过程,已经加到
http://httl.github.com第4章。
性能和设计,理论上也是质量的一部分,但之前已经分析过了,这里不再复述,
请参见:
http://httl.github.com第2章和第3章。
先来看看静态代码的分析:
1. 单元测试
单元测试覆盖率: (分析工具EclEmma)
HTTL对所有语法,指令,函数,都有相应模板进行测试,参见:
https://github.com/httl/httl/tree/master/src/test/resources/comment/templates
2. FindBugs检测
已通过FindBugs最新版本(2.0.2)检测,零发现。参见FindBugs能发现的问题:
http://findbugs.sourceforge.net/bugDescriptions.html
3. JDepend检测
已通过JDepend检测检测,无环依赖,稳定度与抽象度比正常,参见4.1.3分包设计章节。
我们再来看看运行时的稳定性分析:
4. 稳定性测试
在长时间重复运行所有单元测试后,CPU保持平稳:(分析工具JVisualVM)
内存也保持平稳,以YoungGC为主:
虽然HTTL大量使用字节码生成以提升性能,但因为有全量缓存,Perm区也是稳定的:
因设置的内存只有500M,而常规已占400多M,在OLD区几乎快满情况下,也只发生3次FullGC:(分析工具jstat)
从下面Dump后的数据可以看出,JDK编译占用了171M内存,如果开启-Xlint:unchecked编译参数会更大。
如果你觉得JdkCompiler内存占用过多,也可以通过配置换成Javassist编译。(分析工具jmap + MAT)
5. Profile分析
5.1 CPU分析
测试用例为长时间跑模板渲染过程,因解析后有缓存,所以CPU几乎全耗在渲染过程,
解析过程占比较小,符合预期:(分析工具JProfiler)
因同时测试了Writer和OutputStream两种场景,所以上图中各分一半。
展开其中一个渲染过程,各模板比较均匀,占比都不大,没有出现绝对热点,符合预期:
从上图可以看上,相对而言,xml.httl和include_withfilter.httl较慢,展开如下:
可以看出,主要消耗在xstream的parseXml解析和filter的escapseXml转义上。
XML的解析和处理本身就很耗时,在可接受范围内,并且不是核心组件。
长时间运行后,因样本少,xstream解析数据被缓存,所以时间都集中到了escapseXml的charAt上。
注意,上面的图中,浅红色表示当前方法消耗,深红色表示子函数消耗总和。
即然占比如此大,我们来看下代码:
首先String.charAt只是一个char[]下标取值,已经足够简单,不存在性能问题:
public char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index + offset];
}
那再来看看HTTL的escapseXml:
public static String escapeXml(String value) {
if (value == null || value.length() == 0) {
return value;
}
int len = value.length();
StringBuilder buf = null;
for (int i = 0; i < len; i ++) {
char ch = value.charAt(i);
switch (ch) {
case '&':
if (buf == null) {
buf = new StringBuilder(len * 2);
if(i > 0) {
buf.append(value.substring(0, i));
}
}
buf.append("&");
break;
case '<':
if (buf == null) {
buf = new StringBuilder(len * 2);
if(i > 0) {
buf.append(value.substring(0, i));
}
}
buf.append("<");
break;
case '>':
if (buf == null) {
buf = new StringBuilder(len * 2);
if(i > 0) {
buf.append(value.substring(0, i));
}
}
buf.append(">");
break;
case '\"':
if (buf == null) {
buf = new StringBuilder(len * 2);
if(i > 0) {
buf.append(value.substring(0, i));
}
}
buf.append(""");
break;
case '\'':
if (buf == null) {
buf = new StringBuilder(len * 2);
if(i > 0) {
buf.append(value.substring(0, i));
}
}
buf.append("'");
break;
default:
if (buf != null) {
buf.append(ch);
}
break;
}
}
if (buf != null) {
return buf.toString();
}
return value;
}
从代码中可以看出escapseXml已经做了一些优化:
* 在没有发现特殊符前,不创建StringBuilder对象。
* 在发现第一个特殊符时,将将之前的内容,一次性拷到StringBuilder中。
* StringBuilder对象以两倍长度创建,防止扩容带来数据迁移。
* 通过switch每字符,以最短路径分发处理逻辑。
因escapseXml在没有发现特殊符时,只是通过charAt遍历字符串,不会做其它动作,所以长时间运行后,会显得charAt比较热,要过滤至少要遍历一遍,这已经是最低复杂度,所以并不是什么问题。
在压测Apache开源commons-lang中的StringEscapeUtils中的escapeXml后,发现性能甚至不如HTTL的实现。
那也看下commons-lang的StringEscapeUtils源代码:(注释中有说明它慢的原因)
public static String escapeXml(String str) {
if (str == null) {
return null;
}
return Entities.XML.escape(str);
}
public String escape(String str) {
// 这里总是创建StringWriter,如果str没有特殊符,这样首先会浪费创建Writer对象的成本。
// 其次浪费将一个个字符写到writer中,再toString回来的大量性能,而且没有特殊符是大概率事件。
// HTTL在没有特殊符时是直接返回原始串的,不创建任何对象,不做任何来回拷贝。
// 另外,StringWriter里面封装的StringBuffer,它的所有方法是带同步锁的,而HTTL采用无锁的StringBuilder。
StringWriter stringWriter = createStringWriter(str);
try {
this.escape(stringWriter, str);
} catch (IOException e) {
throw new UnhandledException(e);
}
return stringWriter.toString();
}
public void escape(Writer writer, String str) throws IOException {
int len = str.length();
for (int i = 0; i < len; i++) {
char c = str.charAt(i);
// 这里使用map的hash查找实体的名称,比HTTL的switch慢。
String entityName = this.entityName(c);
if (entityName == null) {
if (c > 0x7F) {
writer.write("&#");
writer.write(Integer.toString(c, 10));
writer.write(';');
} else {
writer.write(c);
}
} else {
writer.write('&');
writer.write(entityName);
writer.write(';');
}
}
}
当然,如果你有更好的实现,欢迎提供,非常感谢。
你可以通过配置切换实现:
value.filters=com.your.YourEscapeXmlFilter
5.2 内存分析
内存中以char[]和String最多,因为模板本身是大量文本处理,符合预期:(分析工具JProfiler)
过滤HTTL自身的类,因Context为会话域模型,每次执行都会创建Context,所以Context类最多,它比较轻量,符合预期:
长时间运行后,Context等实例数保持稳定,并没有爆炸式增长,表示可有效回收,符合预期:
分享到:
相关推荐
HTTL(Hash Template Text Language)是一种轻量级的Java模板引擎,主要应用于Web开发中的视图层渲染。...`httl-1.0.11.jar` 包是HTTL库的...通过深入理解和实践,开发者可以充分利用HTTL的优势,提升开发效率和项目质量。
HTTL模板引擎源码 HTTL(Hyper-Text Template Language)是一个高性能的JAVA开源模板引擎,适用于动态HTML页面输出,可替代JSP页面,它的指令和Velocity相似。
本篇文章将对四个流行的Java模板引擎——Velocity、FreeMarker、Smarty4j以及HTTL进行效率分析,旨在探讨它们在处理业务逻辑编译和性能方面的优劣。 1. Velocity: Velocity是Apache软件基金会的一个开源项目,以其...
超文本模板语言( HTTL )和引擎 文献资料网页:|示例:|用户指南语法:|配置:|开发指南整合:英文|中文设计:英文|中文帮助(常见问题/团队成员):英语|中文 下载https://github.com/httl/httl/tags 或克隆项目...
自己学习用的,基本上采用都是最新版的程序,jre7编译 不建议直接导入,自己新建maven项目,然后一步步的导入文件,这样有利于学习 1分只是象征,如果一分都没有 ...互相学习,互相进步吧!">自己学习用的,基本上采用...
因此,拥有高质量且多样化的素材是提升游戏体验的关键。 首先,我们要了解角色图像。角色通常包括主角和各种NPC(非玩家角色),他们的设计直接影响到玩家对角色的第一印象。在魔塔游戏中,角色通常为像素风格,...
T4模板使用及CSHTMLT4模板使用及CSHTML
HTML颜色库是一个全面的资源,包含了几乎所有的颜色代码值,为网页设计、前端开发以及其他需要颜色编码的应用提供了极大的便利。这个库不仅包含了基本的颜色名称,还涵盖了十六进制(Hex)、RGB、RGBA、HSL以及HSLA...
在IT行业中,文件的上传与下载是Web应用中常见的功能,尤其在企业级系统中更是不可或缺。本技术探讨的是如何使用Java和JSP实现这一功能,同时涉及到了过滤器(Filter)和登录验证的实践。以下将详细介绍这些知识点。...
再者,文档中提到了电路上的一些基本知识,如电路系列的缩写符号,如TTL(晶体管-晶体管逻辑)、HTTL(高速TTL)、CMOS(互补金属氧化物半导体)等,这些都是集成电路领域常见的逻辑门类型。TTL系列包括不同速度和...
考试时间:120分钟 一、单项选择题(每题1分,共50分) MP3代表的含义 A、一种视频格式 B、一种音频格式 C、一种网络协议 D、软件的名称 超文本标记语言是指 A、 WWW B、 HTTL C、 HTML D、 VRML CD-ROM是指 A、...
一、单项选择题(每题1分,共50分) 1. MP3代表的含义(B) A、一种视频格式 B、一种音频格式 C、一种网络协议 D... A、 WAV波形文件比MIDI文件的音乐质量高 B、存储同样的音乐文件,WAV波形文件比MIDI文件的存储量大 C
第一代TTL包括LTTL(低阈值TTL)和HTTL(高阈值TTL),其中输入级引入了多发射极晶体管,输出级采用了有源负载,显著提升了速度。第二代TTL则包含了STTL(标准TTL)和LSTTL(低功耗TTL),在保持速度优势的同时,...
《2018年m301H盒子修复教程》 在数字娱乐设备领域,智能电视盒子因其便捷的网络功能和丰富的应用体验而备受青睐。然而,设备在使用过程中难免会出现一些问题,如系统崩溃、无法启动等,这就需要我们进行故障修复。...
标题中的“TTL完美破解固件备份M301H_3798mv300h TTL完美破解固件备份 救砖.7z”指的是一个针对特定型号(M301H)设备的固件备份文件集,其中包含了多个关键的系统组件。这个7z压缩包显然用于备份或恢复设备的固件,...
TTL电路还有多种类型,如中速TTL、高速TTL(HTTL)、肖特基TTL(STTL)、低功耗TTL(LTTL)、低功耗肖特基TTL(LSTTL)和先进低功耗肖特基TTL(ALSTTL)等,它们在速度、功耗和性能上有不同的优化。 总的来说,这一...
随后,为了进一步降低功耗,诞生了低功耗系列LTTl和追求更高速度的高速系列HTTL。到了第二代,肖特基箝位系列(STTL)和低功耗肖特基系列(LSTTL)的出现标志着TTL电路性能的进一步优化。进入第三代,采用等平面工艺...
如果在HTTL中引入Java,JSP则应运而生 2 Web应用体系结构:高层概述 考试要求 什么是容器,容器能带给你什么? 代码里有什么 命名servlet,使用DD将Servlet映射到URL 故事:Bob构建了一个速配网站(MVC) ...
如果在HTTL中引入Java,JSP则应运而生 2 Web应用体系结构:高层概述 考试要求 什么是容器,容器能带给你什么? 代码里有什么 命名servlet,使用DD将Servlet映射到URL 故事:Bob构建了一个速配网站(MVC) ...