為什么JSP會(huì)比Beetl慢
許多人都不相信這個(gè)事實(shí),作為前端常用渲染技術(shù),JSP比Beetl慢。如果稍微了解這倆種技術(shù)的人,會(huì)分析:JSP是編譯成class的,而 Beetl總是解釋執(zhí)行的。JSP肯定會(huì)比Beetl快。然而,事實(shí)并不是這樣,通過了許多性能測(cè)試,證明,Beetl還是要快的,如下是TEB模板引擎 性能基準(zhǔn)測(cè)試結(jié)果:
可以看出,代表Beetl的綠色的,性能高于代表JSP的黃色大約2倍。
還有個(gè)帖子來自osc:http://my.oschina.net/tangcoffee/blog/303865,壓力測(cè)試jsp和beetl,證明beetl性能是JSP的2倍,如下是截取的部分?jǐn)?shù)據(jù)
采用jfinal+beetl模板,apache ab壓力測(cè)試結(jié)果
-
Time taken for tests: 0.656 seconds
-
Complete requests: 1000
-
Time per request: 32.813 [ms] (mean)
未采用beetl,apache ab測(cè)試結(jié)果:
-
Time taken for tests: 1.297 seconds
-
Complete requests: 1000
-
Time per request: 64.844 [ms] (mean)
究竟怎么回事情,使得編譯執(zhí)行的JSP執(zhí)行比解釋執(zhí)行的Beetl慢。基本上來說,Beetl并沒有做出超越常規(guī)的性能優(yōu)化,而是JSP本身性能優(yōu)化不夠導(dǎo)致的。
第一: JSP對(duì)靜態(tài)文本處理的不夠好 。
如果你看看JSP編譯的后的java代碼(以Tocmat7為例),你會(huì)發(fā)現(xiàn),JSP并沒有優(yōu)化好靜態(tài)文本輸出。如下一個(gè)JSP代碼
- <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
- pageEncoding="UTF-8"%>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
- <title>Test JSP</title>
- </head>
- <body>
- <%
- String a = "Test JSP";
- %>
- <%=a %>
- </body>
- </html>
Tomcat7 會(huì)編譯成為
- out.write("<html>\r\n");
- out.write("<head>\r\n");
- out.write("<meta http-equiv=\"Content-Type\"
- content=\"text/html; charset=ISO-8859-1\">\r\n");
- out.write("<title>Test JSP</title>\r\n");
- out.write("</head>\r\n");
- out.write("<body>\r\n");
- String a = "Test JSP";
- out.write('\r');
- out.write('\n');
- out.print(a );
- out.write("\r\n");
- out.write("</body>\r\n");
- out.write("</html>");
可以看出,對(duì)于靜態(tài)文本,JSP會(huì)多次調(diào)用out.write方法,而write方法內(nèi)部,每次調(diào)用,都會(huì)做flush檢測(cè)等耗時(shí)機(jī)制。因此,更好的方式應(yīng)該是將靜態(tài)文本合并一次性輸出,應(yīng)該是下面這種會(huì)更好點(diǎn)
// 期望JSP的樣子
- out.write("<html>\r\n<head>\r\n ....<body>\r\n“);
- String a = "Test JSP";
- out.write("\r\n“);
- out.print(a );
- out.write("\r\n</body>\r\n</html>");
第二 就算JSP的實(shí)現(xiàn)做了如上更改,靜態(tài)文本處理還有優(yōu)化空間。這是因?yàn)榛ヂ?lián)網(wǎng)傳輸?shù)亩M(jìn)制,因此會(huì)存在一個(gè)將靜態(tài)文本轉(zhuǎn)成 byte[] 輸出的過程,這是一個(gè)耗費(fèi)CPU操作的過程,也就是JSP里的write操作,內(nèi)部還大量的編碼,而且,隨著JSP一次次渲染,編碼是一次一次重復(fù),實(shí)驗(yàn) 證明,這極大的降低了JSP性能。通過如下偽代碼可以驗(yàn)證
- public static void main(String[] args)throws Exception {
- String text = "<html>你好中文!你好中文!你好中文!</html>";
- {
- //模擬jsp
- long start = System.currentTimeMillis();
- for(int i=0;i<1000000;i++){
- byte[] bs = text.getBytes("UTF-8");
- write(bs);
- }
- long end = System.currentTimeMillis();
- System.out.println("jsp total="+(end-start));
- }
- {
- // 模擬beetl
- long start = System.currentTimeMillis();
- byte[] bs = text.getBytes("UTF-8");
- for(int i=0;i<1000000;i++){
- write(bs);
- }
- long end = System.currentTimeMillis();
- System.out.println("beetl total="+(end-start));
- }
- }
- public static void write(byte[] bs){
- }
輸出是:
-
jsp total=228
-
beetl total=3
可見Beetl將靜態(tài)文本預(yù)先編碼成二進(jìn)制,會(huì)提高性能很多。而通常JSP,總是靜態(tài)文本多過JSP Code的
第三,JSP在JSTL做的不夠完美,也導(dǎo)致性能很差。
由于JSP是基于Java語言,語言本身是OO的,很多地方不適合模板場(chǎng)景使用,因此,自然而然采用JSTL來彌補(bǔ)JSP的不足,這也是后來很多項(xiàng)目都基本上采用了JSTL來寫模板。然而,JSTL的性能更加有問題。比如下一個(gè)簡(jiǎn)單的JSTL判斷
- <c:choose>
- <c:when test="${param.newFlag== '1' || param.newFlag== '2'}">
- <th>1 or 2 <font color="Red">*</font>
- </c:when>
- </c:choose>
在我最初的想象里,我認(rèn)為jsp至少會(huì)編譯成如下代碼:
//期望JSP能編譯成如下代碼
- if(request.getParameter("newFlag").equals("1")
- ||request.getParameter("newFlag").equals("2")){
- out.print(...)
- }
但事實(shí)并不是這樣,對(duì)于如上JSTL,編譯成
- // 實(shí)際上JSP編譯的代碼
- out.write((java.lang.String)
- org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(
- "${param.newFlag== '1' || param.newFlag== '2'}",
- java.lang.String.class,
- (javax.servlet.jsp.PageContext)_jspx_page_context, null, false));
也就是,JSP并沒有如預(yù)期的預(yù)編譯成java代碼,而是動(dòng)態(tài)解釋執(zhí)行了 test條件,這樣,性能不差才怪呢.
綜上所述,JSP之所以在基準(zhǔn)測(cè)試還是實(shí)際的測(cè)試,都比Beetl慢不少,是因?yàn)樗o態(tài)文本輸出方面沒有去做積極的優(yōu)化。像JSTL那樣的的解釋執(zhí)行也極大的拖了JSP后退,而Beetl避免了這些問題。
責(zé)任編輯:售電衡衡
-
權(quán)威發(fā)布 | 新能源汽車產(chǎn)業(yè)頂層設(shè)計(jì)落地:鼓勵(lì)“光儲(chǔ)充放”,有序推進(jìn)氫燃料供給體系建設(shè)
2020-11-03新能源,汽車,產(chǎn)業(yè),設(shè)計(jì) -
中國自主研制的“人造太陽”重力支撐設(shè)備正式啟運(yùn)
2020-09-14核聚變,ITER,核電 -
探索 | 既耗能又可供能的數(shù)據(jù)中心 打造融合型綜合能源系統(tǒng)
2020-06-16綜合能源服務(wù),新能源消納,能源互聯(lián)網(wǎng)
-
新基建助推 數(shù)據(jù)中心建設(shè)將迎爆發(fā)期
2020-06-16數(shù)據(jù)中心,能源互聯(lián)網(wǎng),電力新基建 -
泛在電力物聯(lián)網(wǎng)建設(shè)下看電網(wǎng)企業(yè)數(shù)據(jù)變現(xiàn)之路
2019-11-12泛在電力物聯(lián)網(wǎng) -
泛在電力物聯(lián)網(wǎng)建設(shè)典型實(shí)踐案例
2019-10-15泛在電力物聯(lián)網(wǎng)案例
-
新基建之充電樁“火”了 想進(jìn)這個(gè)行業(yè)要“心里有底”
2020-06-16充電樁,充電基礎(chǔ)設(shè)施,電力新基建 -
燃料電池汽車駛?cè)雽こ0傩占疫€要多久?
-
備戰(zhàn)全面電動(dòng)化 多部委及央企“定調(diào)”充電樁配套節(jié)奏
-
權(quán)威發(fā)布 | 新能源汽車產(chǎn)業(yè)頂層設(shè)計(jì)落地:鼓勵(lì)“光儲(chǔ)充放”,有序推進(jìn)氫燃料供給體系建設(shè)
2020-11-03新能源,汽車,產(chǎn)業(yè),設(shè)計(jì) -
中國自主研制的“人造太陽”重力支撐設(shè)備正式啟運(yùn)
2020-09-14核聚變,ITER,核電 -
能源革命和電改政策紅利將長(zhǎng)期助力儲(chǔ)能行業(yè)發(fā)展
-
探索 | 既耗能又可供能的數(shù)據(jù)中心 打造融合型綜合能源系統(tǒng)
2020-06-16綜合能源服務(wù),新能源消納,能源互聯(lián)網(wǎng) -
5G新基建助力智能電網(wǎng)發(fā)展
2020-06-125G,智能電網(wǎng),配電網(wǎng) -
從智能電網(wǎng)到智能城市
-
山西省首座電力與通信共享電力鐵塔試點(diǎn)成功
-
中國電建公司公共資源交易服務(wù)平臺(tái)摘得電力創(chuàng)新大獎(jiǎng)
-
電力系統(tǒng)對(duì)UPS的技術(shù)要求