為什么JSP會比Beetl慢
許多人都不相信這個事實,作為前端常用渲染技術,JSP比Beetl慢。如果稍微了解這倆種技術的人,會分析:JSP是編譯成class的,而 Beetl總是解釋執(zhí)行的。JSP肯定會比Beetl快。然而,事實并不是這樣,通過了許多性能測試,證明,Beetl還是要快的,如下是TEB模板引擎 性能基準測試結果:
可以看出,代表Beetl的綠色的,性能高于代表JSP的黃色大約2倍。
還有個帖子來自osc:http://my.oschina.net/tangcoffee/blog/303865,壓力測試jsp和beetl,證明beetl性能是JSP的2倍,如下是截取的部分數(shù)據(jù)
采用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)
究竟怎么回事情,使得編譯執(zhí)行的JSP執(zhí)行比解釋執(zhí)行的Beetl慢?;旧蟻碚f,Beetl并沒有做出超越常規(guī)的性能優(yōu)化,而是JSP本身性能優(yōu)化不夠導致的。
第一: JSP對靜態(tài)文本處理的不夠好 。
如果你看看JSP編譯的后的java代碼(以Tocmat7為例),你會發(fā)現(xiàn),JSP并沒有優(yōu)化好靜態(tài)文本輸出。如下一個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 會編譯成為
- 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>");
可以看出,對于靜態(tài)文本,JSP會多次調(diào)用out.write方法,而write方法內(nèi)部,每次調(diào)用,都會做flush檢測等耗時機制。因此,更好的方式應該是將靜態(tài)文本合并一次性輸出,應該是下面這種會更好點
// 期望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的實現(xiàn)做了如上更改,靜態(tài)文本處理還有優(yōu)化空間。這是因為互聯(lián)網(wǎng)傳輸?shù)亩M制,因此會存在一個將靜態(tài)文本轉(zhuǎn)成 byte[] 輸出的過程,這是一個耗費CPU操作的過程,也就是JSP里的write操作,內(nèi)部還大量的編碼,而且,隨著JSP一次次渲染,編碼是一次一次重復,實驗 證明,這極大的降低了JSP性能。通過如下偽代碼可以驗證 輸出是: jsp total=228 beetl total=3 可見Beetl將靜態(tài)文本預先編碼成二進制,會提高性能很多。而通常JSP,總是靜態(tài)文本多過JSP Code的 第三,JSP在JSTL做的不夠完美,也導致性能很差。 由于JSP是基于Java語言,語言本身是OO的,很多地方不適合模板場景使用,因此,自然而然采用JSTL來彌補JSP的不足,這也是后來很多項目都基本上采用了JSTL來寫模板。然而,JSTL的性能更加有問題。比如下一個簡單的JSTL判斷 在我最初的想象里,我認為jsp至少會編譯成如下代碼: //期望JSP能編譯成如下代碼 但事實并不是這樣,對于如上JSTL,編譯成 也就是,JSP并沒有如預期的預編譯成java代碼,而是動態(tài)解釋執(zhí)行了 test條件,這樣,性能不差才怪呢. 綜上所述,JSP之所以在基準測試還是實際的測試,都比Beetl慢不少,是因為他靜態(tài)文本輸出方面沒有去做積極的優(yōu)化。像JSTL那樣的的解釋執(zhí)行也極大的拖了JSP后退,而Beetl避免了這些問題。