最近发现公司系统压力比较大,CPU常年满负荷运转,uptime超过3.0,用户反应后台程序使用困难,速度很慢。
由于当时在系统设计时内部采用XML数据生成,由XSL进行表现描述,通过XSLT转换成HTML用于前台显示。
在跟踪日志后发现,对于XSLT这段代码还从来没有优化过,由于系统大量表现都是使用XSLT进行转换的,如果可以提高XSLT的转换效率那将是非常有意义的一件事情。
由于在开发时是采用的jdom用户生成xml,XSLT用的是JDK1.4自带的JAXP,对效率没有产生过怀疑。
上网查了一些资料,找到一个benchmark report,

http://www.xml.com/pub/a/2001/03/28/xsltmark/results.html
发现仅在XSLT中最快的,性能最好的是MS XML Parser包,其次是XSLTC,再其次是ORACLE的xml包。
而对于Parser和XSLT综合性能最好的是一个XT的开发包,据说是历史上第一个实现XSLT的人开发的,还好网站还在,不过最新的Source已经是2002的呢,已经相当古老了。
先到http://www.blnz.com/上下载了XT的binary和source包,进行试验,使用后发现同样的代码逻辑,确实在xslt这一段性能有所提高,但是对GBK的xml转换有点问题,在修改后一行代码后,重新build一个jar,就ok了。
这样基本解决了我的问题,但是发现上面那个图表中提到xsltc应该是一种更好的方法。在查阅了一些资料后,发现JAXP1.3中包含了xsltc,还有就是xalan-j中也有,由于对apache.org比较有倾向性,就选用了xalan-j作为试验对象,在IBM DW看了一篇教程后,改造了xalan-j的一个samples,完成了我的测试程序,这样也就完成我所做的第一步工作。
第二步是准备测试案例,我准备一个1.6MB的xml文件,和一个相对应的xsl文件,大小约为2K。
第三步就是进行对比测试,测试结果如下:

从图中可以看出XT的性能要好于JAXP,而用XSLTC方法第一次由于有compile的消耗,加上translet的时间和XT几乎相等,但是由于compile后的translet被保存,在第二次使用中就会又有一倍的性能提高,这个还是很可观的。
对于xml转换很频繁的应用还是要考虑使用XSLTC,毕竟它比普通的XSLT的性能提高了5倍多,可以说是质的不同了。
tips:
对于使用Xalan-j,在JDK5.0中最新版可以使用,但在jdk1.4中不行,因为jdk1.4本身自带了一个Xalan-j,而且是一个有错误的版本,所以会导致使用Xalan-j 最新版的命令行出现异常,对于这个问题可以参见http://lists.oasis-open.org/archives/docbook-apps/200401/msg00063.html,和https://www6.software.ibm.com/developerworks/cn/education/xml/x-xalanj/tutorial/index.html
对于问题1一个简单的方法是在%JAVA_HOME%/JRE/LIB目录下,建一个endrosed目录,把xalan-j的相关文件copy过去,就可以覆盖掉jdk内置的xalan了,通过命令java org.apache.xalan.processor.XSLProcessorVersion 可以进行验证。也可以在命令行上制定参数-Djava.endorsed.dirs 进行指定
对于使用xsltc把XSL文件编译成具体类后,需要把具体的类放入CLASSPATH才能在使用
但对于编程方式,可以无需顾忌CLASSPATH,因为每次都会重新编译translet的,当然也可以采用静态编译的方法,不过我没有去试验。
对于xsltc编译出来的translet是否会出现线程安全的问题,还没有查看文档进行验证,需要关注一下,个人感觉应该是线程安全的,否则又要搞translet pool,那就比较麻烦,我想xalan-j也不会蠢到这个地步。
对于具体性能还有更加苛刻的要求的话,可能需要看一下C接口的XML相关开发包了,