多年前看過周星馳的電影《功夫》,裡頭的大 Boss 火雲邪神有一句經典臺詞:天下武功,無堅不破,唯快不破。
周星馳最後通過變得比火雲邪神更快,輕鬆擊敗火雲邪神
在當時我對這句 「天下武功,無堅不破,唯快不破」 並不以為然,直到 2016 年,jfinal 社區有位小夥伴用 jfinal 做了一個電影網站《憨憨電影》,傳送門 。看了裡面的《閃電俠》這部美國科幻劇,傳送門 ,才意識到唯快不破的深刻內涵,閃電俠本質就一個核心能力:「快」。運動速度可以自我調整到無比之快。就 「快」 這麼一個特性,組合達成無數強大的功能。
例如,圍繞颶風做反方向圓周運動,製造反作用力輕鬆化解颶風
例如,快速奔跑與空氣摩擦製造閃電並發射出去,擊敗 Sand Demon
當然,還可以用「快」實現撩妹功能,撩到的還是美豔的女超人
一個 「快」 字,讓原本棘手的問題得以巧妙化解,使得閃電俠戰無不勝
科幻歸科幻,回到現實中,那麼到底這個 「唯快不破」 有沒有沒道理呢?在 jfinal 這些年的實戰中被證實確有道理,例如 jfinal 在 6 年前率先使用 JFinal.start(...) 的方式秒起項目,不用配置 tomcat/jetty,修改原始碼不用重啟項目,本質就是 「快」,以至於幾年以後發布的 spring boot 也用了這一招來啟動項目
再例如 jfinal 完全消滅掉 xml 配置,獨創 API 引導式配置,開發者在開發時除了不再被 xml 噪音幹擾以外,還可以不用去記憶各種繁雜的配置,API 引導式配置不但可以利用 IDE 的代碼提示而且還可以通過參數名、注釋內容立即了解配置的含義。本質還是 「快」,以至於幾年以後才發布的 spring boot 也去除 xml 並引入了與 jf API 引導式配置相似的設計 java config
再例如,jfinal 極大提升開發效率,往往在他人還在寫配置文件的時候,jfinal 小夥伴們已然實現了功能產品可以快速上線,更早獲取用戶對產品的反饋,極大提升了產品迭代速度,這在如今分秒必爭高速發展的網際網路時代是創業成功的關鍵。如果產品的進化速度無比快,將是不可戰勝的
以往 jfinal 的快,更多體現的是上手快、啟動快、開發快、學習快、擴展快。那麼這次 jfinal 3.3 關注一下運行起來的性能快不快? 以下是 jfinal 與 spring + mybatis 性能測試結果
jfinal 性能是 spring + mybatis 的 4.56 倍,這裡是測試項目連結:https://gitee.com/jfinal/jfinal-performance
以下是 jfinal 模板引擎與 freemarker、velocity 性能測試結果
jfinal 模板引擎性能是 freemarker 的 4.27 倍,是 velocity 的 3.42,不僅速度快而且內存佔用更小,這裡是測試項目連結:https://gitee.com/jfinal/enjoy-performance
jfinal 3.3 對模板引擎做了十分細緻的性能優化,性能大幅提升,jf 3.3 對模板引擎主要採用了如下優化方法:
採用 "籠罩" 式設計,引入 WriterBuffer 覆蓋於入參 Writer、OutputStream 之上,使用內部的 byte[] buffer、char[] buffer、DateFormat 儘可能避免內存分配
ExprList、StatList 避免在單一內部對象時 for 循環
添加 byte 模式,使得模板靜態內容只 encode 一次
fnv 64 算法代替 StingBuider 拼接字符串生成 hash
優化 Integer、Double、Float、Boolean 等類型數據輸出
優化日期類型格式化,回收利用 SimpleDataFormat
除了模板引擎性能上的大幅提升以外,jfinal 3.3 還進行了將近 50 項增強與改進
1:模板引擎添加 byte 輸出模式
template.render(data, request.getOutputStream());
該模式最大的好處是,在 web 環境下直接輸出 byte 流,避免對模板文件中的靜態文本部分做 encode 操作,性能可提升一到兩倍
2:添加 ControllerFactory,支持用戶接管 controller 生命周期
me.setControllerFactory(new FastControllerFactory());
不僅可以控制 controller 生命周期、重複回收利用 controller 對象,還可以方便進行 IOC、DI 動作
3:增強 PropKit、Prop,添加 append 系列方法
PropKit.use("dev.txt").append("prod.txt");
大多數情況下開發環境與生產環境配置文件的配置項都相同,引入 append 方法,可以讓 prod.txt 配置文件中僅添加與 dev.txt 中不同的配置項,例如 password,極大減少配置工作量,也減少了出錯的可能性,感謝 @t-io 作者提出的好建議
4:添加 #number 指令,支持格式化輸出數值數據
#number(3.1415926, "#.##")#number(0.9518, "#.##%")#number(300000, "光速為每秒 ,### 公裡。")
5:Model、BaseModel、MappingKit 改由模板引擎實現
public class #(mappingKitClassName) { public static void mapping(ActiveRecordPlugin arp) { #for (tableMeta : tableMetas) arp.addMapping("#(tableMeta.name)", "#(tableMeta.primaryKey)", #(tableMeta.modelName).class); #end }}
由字符串拼接改由模板引擎實現以後,不僅便於可讀性與維護性,而且十分有利於自由定製個性化模板
6:支持自定義 ActionHandler,徹底接管 action 請求
me.setActionHandler(new MyActionHandler());
7:Controller.renderToString(...) 支持 viewPath
renderToString("reply_item.html");
老版本中要使用全路徑,新版本更省代碼,viewPath 規則與其它 render 方法完全一致,不增加學習成本,全路徑使用方式也天然兼容。
jfinal 3.3 版本如上的增強與改進還有很多,為限制篇幅,在此不在贅述,後續會單獨補充詳細的 jfinal-3.3-changelog.txt
ONE MORE THING:俱樂部將直播 jfinal 3.3 的各種性能優化技術,優化所使用的工具、優化的方法與過程,對此感興趣的同學可加入俱樂部:http://jfinal.com/club