您的位置:首页 > Web前端 > JavaScript

jsp与模板引擎性能

2016-01-12 23:53 435 查看
在讨论模板引擎的性能之前必须先明确几个问题:

1. 在同等优化条件下,java原生代码最快。

2. jsp在只采用java脚本编写的情况下,可以认为与java原生代码的性能相当,仍然是在同等优化条件下。

3. 编译性能可以不考虑,因为都是编译一次,多次运行,对运行期没有影响。

有些模板引擎的性能优于jsp,这个只是由于对比的jsp容器做的优化较少,而模板引擎做了大量优化。

例如tomcat的jsper引擎,优化做的比较少,在模板引擎中很常见的优化手段在jsper中都没有做,所以一些模板引擎的性能超越tomcat的jsp引擎并不奇怪。

如果采用同等的优化条件,无论是什么模板引擎,性能最多能与只采用java脚本的jsp性能相当,不可能超越。除非这个模板引擎生成的字节码比jdk自带的编译器生成的字节码效率高。

jsp技术的几个常规优化点:

1. 把字符串常量定义为静态char数组,这个优化效果是很明显的。以下示例代码是jsp引擎编译之后的java代码,例如:

out.write("Hello World !");

优化成:

out.write(_jsp_string_1, 0, _jsp_string_1.length);

private static final String _jsp_string_1 = "Hello World !".toCharArray();

这样做的好处:1,节省内存,减少内存碎片,减轻gc压力;2,减少内存申请;3,减少方法调用。

tomcat的jsp引擎并没有采用这样的优化,resin的jsp引擎使用了这样的方式。

2. 拆分大方法为小方法。

JVM在运行到热点方法的时候会编译为本地代码运行,性能更高,但是如果方法体过大,则JIT不会生效。

tomcat对每个标签都会编译为一个方法,而resin不会。

我没有看过tomcat的源码是如何实现的,但是我觉的这种方式是有限制的:被编译的方法不能使用java脚本。

3. 尽可能减少调用el引擎。例如: ${userName}这个el表达式就可以不调用el引擎,仅仅输出pageContext.getAttribute("userName")就可以了。

4. 使用fastJstl模式,例如: <c:if test="${user.age > 18}">Hello !</c:if>,可以编译为:

if(elEngine.getBoolean("user.age > 18")) {

out.wirte("Hello !");

}

而不是编译成IfTag,然后调用一堆的IfTag的方法。

tomcat对任何标签都会编译出标签对象,并且按照标签的生命周期调用执行,而resin则采用了fastJstl模式,并且默认是开启状态。不知道tomcat的jsper引擎是否支持该模式。

影响jsp页面性能的几个关键点:

1. el表达式,可以说对jsp性能影响最大的就是el表达式了。

el表达式一般是解释执行,而且大量使用反射,java的反射性能很低,与原生的java代码相比,性能相差好几个数量级。

如果页面上有相当多的el表达式,性能差一点都不奇怪。

2. 标签

jstl的生命周期决定了一个简单的方法调用一旦使用标签来实现,最终要执行的指令数立即几倍甚至几十倍的增加。而且一个标签在初始化的时候很可能也存在el调用。

3. 能用el标签输出的不要用标签输出,例如: ${user.name}优于<c:out value="${user.name}"/>,后者比前者还要多执行一次标签创建和调用。

不过这个例子有些jsp引擎会优化为:out.write(elEngine.getString("user.name")); 与直接写el表达式的效果一样。

除去以上两点,如果一个jsp页面只采用java脚本编写,并且jsp引擎做适度的优化,那么jsp无疑是性能最好的。

但是像tomcat这种很流行的jsp容器在jsp的性能上优化的并不多。而目前很多java的模板引擎做很很多性能优化,甚至很多性能都超过了tomcat的jsp引擎。

例如HTTL,从实现原理上看,上面提到的优化手段全都采用了,而且它是无反射调用的,性能与原生代码相当。

我所知道的httl所采用的优化手段:

1. 无反射调用。jsp除非采用原生代码编写,否则很难做到无反射。

2. 字符串常量直接编译为byte数组,这个优化更彻底。jsp里面不可能采用这个优化手段,因为api接口JspWriter是字符流。

httl所采用的优化手段都是在jsp里面很难做到或者由于api的限制没法做的,所以httl的性能可以认为是超过jsp的。当然这不是说jsp性能不好,而是说httl可以采用的优化手段比jsp多,而且像tomcat这种连一些常规的优化都没做。

唯一不爽的是httl的语法不是我喜欢的类型,这是个人喜好问题,抛去这些,httl是我见过的性能最好的。

模板引擎的性能测试

一般的性能测试最好在单线程模式下进行。并发下的测试唯一有用的是测试是否存在线程安全的问题,高并发下测试结果几乎没有参考价值,尤其是那些把线程数都压的不够用了,测试结果就更不可信了。因为当大量线程都在等待执行机会的时候,讨论那个执行更快完全没有意义。

例如随便用任何一个模板引擎写一个复杂的页面,然后用原生代码写个hello world在高并发下测试一下就知道了,原来性能差不多!例子夸张了点,但大概意思差不多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: