首页Java基础Java源码Java框架设计模式JavaEEJava Web开发视频教程

您现在的位置:首页 >

Java Web开发

关注我们

优就业官方微信
优就业官方微信扫描二维码,即可与小
U亲密互动
优就业官方微博
优就业官方微博扫码关注,更有精彩活动
等你参与
  • 优就业官方QQ号

    优就业官方QQ号

    一键加好友
  • 咨询电话:( 9:00-22:00 )

    400-650-7353

【Java Web开发】为什么JSP会比Beetl慢

2018-03-05 16:43:34

许多人都不相信这个事实,作为前端常用渲染技术,JSP比Beetl慢。如果稍微了解这俩种技术的人,会分析:JSP是编译成class的,而 Beetl总是解释执行的。JSP肯定会比Beetl快。然而,事实并不是这样,通过了许多性能测试,证明,Beetl还是要快的,如下是TEB模板引擎 性能基准测试结果:

可以看出,代表Beetl的绿色的,性能高于代表JSP的黄色大约2倍。

采用jfinal+beetl模板,apache ab压力测试结果

Time taken for tests: 0.656 seconds

Complete requests: 1000

Time per request: 32.813 [ms] (mean)

未采用beetl,apache ab测试结果:

Time taken for tests: 1.297 seconds

Complete requests: 1000

Time per request: 64.844 [ms] (mean)

究竟怎么回事情,使得编译执行的JSP执行比解释执行的Beetl慢。基本上来说,Beetl并没有做出超越常规的性能优化,而是JSP本身性能优化不够导致的。

第一: JSP对静态文本处理的不够好 。

如果你看看JSP编译的后的java代码(以Tocmat7为例),你会发现,JSP并没有优化好静态文本输出。如下一个JSP代码

  1. <%@ page language="java" contentType="text/html; charset=ISO-8859-1"  
  2.     pageEncoding="UTF-8"%>  
  3. <html>  
  4. <head>  
  5. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">  
  6. <title>Test JSP</title>  
  7. </head>  
  8. <body>  
  9. <%  
  10. String a = "Test JSP";  
  11. %>  
  12. <%=a %>  
  13. </body>  
  14. </html>  

Tomcat7 会编译成为

  1. out.write("<html>\r\n");  
  2.       out.write("<head>\r\n");  
  3.       out.write("<meta http-equiv=\"Content-Type\"  
  4.             content=\"text/html; charset=ISO-8859-1\">\r\n");  
  5.       out.write("<title>Test JSP</title>\r\n");  
  6.       out.write("</head>\r\n");  
  7.       out.write("<body>\r\n");  
  8. String a = "Test JSP";  
  9.       out.write('\r');  
  10.       out.write('\n');  
  11.       out.print(a );  
  12.       out.write("\r\n");  
  13.       out.write("</body>\r\n");  
  14.       out.write("</html>");  

可以看出,对于静态文本,JSP会多次调用out.write方法,而write方法内部,每次调用,都会做flush检测等耗时机制。因此,更好的方式应该是将静态文本合并一次性输出,应该是下面这种会更好点

// 期望JSP的样子

  1. out.write("<html>\r\n<head>\r\n ....<body>\r\n“);  
  2. String a = "Test JSP";  
  3. out.write("\r\n“);  
  4. out.print(a );  
  5. out.write("\r\n</body>\r\n</html>");  

第二 就算JSP的实现做了如上更改,静态文本处理还有优化空间。这是因为互联网传输的二进制,因此会存在一个将静态文本转成 byte[] 输出的过程,这是一个耗费CPU操作的过程,也就是JSP里的write操作,内部还大量的编码,而且,随着JSP一次次渲染,编码是一次一次重复,实验 证明,这极大的降低了JSP性能。通过如下伪代码可以验证

  1. public static void main(String[] args)throws Exception {  
  2.   String text = "<html>你好中文!你好中文!你好中文!</html>";  
  3.   {  
  4.    //模拟jsp  
  5.    long start = System.currentTimeMillis();  
  6.    for(int i=0;i<1000000;i++){  
  7.     byte[] bs = text.getBytes("UTF-8");  
  8.     write(bs);  
  9.    }  
  10.    long end = System.currentTimeMillis();  
  11.    System.out.println("jsp total="+(end-start));  
  12.   }  
  13.   
  14.   {  
  15.    // 模拟beetl  
  16.    long start = System.currentTimeMillis();  
  17.    byte[] bs = text.getBytes("UTF-8");    
  18.    for(int i=0;i<1000000;i++){    
  19.     write(bs);  
  20.    }  
  21.    long end = System.currentTimeMillis();  
  22.    System.out.println("beetl total="+(end-start));  
  23.   }  
  24.   
  25. }  
  26.   
  27. public static void write(byte[] bs){  
  28.   
  29. }  

输出是:

jsp total=228

beetl total=3

可见Beetl将静态文本预先编码成二进制,会提高性能很多。而通常JSP,总是静态文本多过JSP Code的

第三,JSP在JSTL做的不够完美,也导致性能很差。

由于JSP是基于Java语言,语言本身是OO的,很多地方不适合模板场景使用,因此,自然而然采用JSTL来弥补JSP的不足,这也是后来很多项目都基本上采用了JSTL来写模板。然而,JSTL的性能更加有问题。比如下一个简单的JSTL判断

  1. <c:choose>  
  2.    <c:when test="${param.newFlag== '1' || param.newFlag== '2'}">   
  3.     <th>1 or 2  <font color="Red">*</font>  
  4.    </c:when>   
  5. </c:choose>  

在我最初的想象里,我认为jsp至少会编译成如下代码:

//期望JSP能编译成如下代码

  1. if(request.getParameter("newFlag").equals("1")  
  2.    ||request.getParameter("newFlag").equals("2")){  
  3.   
  4.     out.print(...)  
  5. }  

但事实并不是这样,对于如上JSTL,编译成

  1. // 实际上JSP编译的代码  
  2. out.write((java.lang.String)  
  3.   org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(  
  4. "${param.newFlag== '1' || param.newFlag== '2'}",  
  5. java.lang.String.class,  
  6. (javax.servlet.jsp.PageContext)_jspx_page_context, nullfalse));  

也就是,JSP并没有如预期的预编译成java代码,而是动态解释执行了 test条件,这样,性能不差才怪呢.

综上所述,JSP之所以在基准测试还是实际的测试,都比Beetl慢不少,是因为他静态文本输出方面没有去做积极的优化。像JSTL那样的的解释执行也极大的拖了JSP后退,而Beetl避免了这些问题。

免责声明:本文来源于网络,由网友提供或网络搜集,仅供个人交流学习参考使用,不涉及商业盈利目的。如有版权问题,请联系本站管理员予以更改或删除。谢谢合作!

猜你喜欢

 
 
咨询中心
优就业微信扫一扫
微信扫一扫

400-650-7353

加入官方微博