在做TinyTemplate的过程中,避免不了要进行性能优化,在群里与同学们讲,结果许多同学都没有接触过这项业务,因此就开一贴子简单介绍一下,希望对感兴趣的同学们有帮助。
用于进行性能分析的工具有JProfiler,JProbe,JProfile等等许多工具,都是大同小异的了。
今天用来示例的同学是JProfiler,由于现在的结果是已经优化的的结果,因此,看到的可优化之处就非常少了。但是可以说明的是,借助工具的帮助,很快的定位到了性能瓶颈的点,只花了少许时间就性能提升了一倍,基本上达到了最大处理能力,再做深度优化,可能还能提高几个百分点的性能,这个时候投入产出比比较不高,因此就没有再继续进行了。
首先看一下测试代码:
- 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);
- }
- }
可以看到,这里一共执行了20万次
把程序跑起来,然后点击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占用内容比较大。
当然,工具只能帮你快速定位,但不能帮你解决问题,怎么优化还是要看你自己的。 期望对您有所帮助。