在做TinyTemplate的过程中,避免不了要进行性能优化,在群里与同学们讲,结果许多同学都没有接触过这项业务,因此就开一贴子简单介绍一下,希望对感兴趣的同学们有帮助。
用于进行性能分析的工具有JProfiler,JProbe,JProfile等等许多工具,都是大同小异的了。
今天用来示例的同学是JProfiler,由于现在的结果是已经优化的的结果,因此,看到的可优化之处就非常少了。但是可以说明的是,借助工具的帮助,很快的定位到了性能瓶颈的点,只花了少许时间就性能提升了一倍,基本上达到了最大处理能力,再做深度优化,可能还能提高几个百分点的性能,这个时候投入产出比比较不高,因此就没有再继续进行了。
首先看一下测试代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
final
class
TinyTemplate {
public
static
void
main(String[] args)
throws
TemplateException {
TemplateEngine engine =
new
TemplateEngineDefault();
engine.setCacheEnabled(
true
);
TemplateContext context =
new
TemplateContextDefault();
context.put(
"outputEncoding"
,
"GBK"
);
context.put(
"items"
, StockModel.dummyItems());
FileObjectResourceLoader html =
new
FileObjectResourceLoader(
"html"
,
null
,
null
,
"D:\\gitpart3\\ebm\\src\\main\\resources\\templates"
);
html.setCheckModified(
false
);
engine.addTemplateLoader( html);
long
start = System.currentTimeMillis();
Writer writer =
new
StringWriter();
for
(
int
i =
0
; i <
200000
; i++) {
engine.renderTemplate(
"/tiny.html"
, context, writer);
}
long
end = System.currentTimeMillis();
System.out.println(end - start);
}
}
|
把程序跑起来,然后点击attach,选择正在运行的进程,然后就开始抓取数据了,选择Record Memory,Record CPU就开始抓取运行数据了。
由于抓取数据,会导致程序运行速度显著下降,但是不会改变程序运行时消耗CPU的比率。
通过上面的图,可以看到,内存消耗情况可以不断的进行正常的回收,说明没有内存泄露情况。
通过上面的图可以看到,程序采用是单线程的方式运行,因此,CPU主要都消耗到main线程上,这个也与程序结构匹配。
通过上图可以看出CPU的消耗情况。
AbstractTemplate类的render中调用的tiny_html类的renderContent方法消耗的最多,达97.1。
其中42.6消耗在U类的p方法上,21.5%消耗在U类的v方法上,12.8消耗在write方法上,11.4%消耗在O.e方法上。
当然可以逐层查看,消耗在哪个方法上。
像图上的情况,经过对内部实现进行深入分析,已经达到接近最优。
因此优化结束。
最终测得20万次的时候在12.x秒到13.x秒之间。
当然,如果有内存泄露,也可以通过这个工具查看内存占用情况:
从上图可以看到,主要是HashMap中缓冲的数据,占用比较大,具体来说,是org.tinygroup.template.runtime.U中的MethodKey占用内容比较大。
当然,工具只能帮你快速定位,但不能帮你解决问题,怎么优化还是要看你自己的。
期望对您有所帮助。