問題出在 validatorFactory 和 validator 這兩個局部對象的初始化上。尤其是初始化 validatorFactory調用Validation#buildDefaultValidatorFactory, 這個方法內部會涉及到xml文件的讀取和類映射,可見,每次都做這個事情,CP... ...
系統運營後臺有個導入線下交易的功能。產品和運營反饋,當excel數據量超過8千條時,會變得超級慢,動輒要等三四十秒。
哎!這麼慢,擱誰能不鬧心呢?
基於此,這兩天,我覺得優化一下,可是,一來二去,從昨天周一到現在眼看兩天了,對代碼進行各種排查和調整,還是沒有達到理想的效果————至少,別讓用戶傻傻等待超過5秒吧,最次也不能超過10秒吧。
這兩天特殊時期,公司的保潔阿姨應該也陽了,始終沒來上班。那麼,衛生工作就得我們上班族自理了。
我四下張望一下,兩個垃圾桶都滿了。再看小伙伴們都在安靜的碼代碼。我就收拾一下吧。在提著垃圾袋扔垃圾的路上,突然靈光乍現。是不是數據校驗那塊導致的呢?————校驗用的是Hibernate的validation-api。
完事回到工位,趕緊試試。
————峰迴路轉。
果然,本地測試才驚人地發現,用Hibernate的校驗工具,8200條數據耗時47s,而直接用apache common的util類校驗,僅需1~2s。
why?
why?
why?
程式使用不當所致。先貼出來關鍵代碼:
import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; public class ValidationUtil { private ValidationUtil() { } /** * 根據註解,校驗參數的工具類 * * @pojo pojo bean * @return 驗證結果 */ public static Result<Void> validate(Object pojo) { if (pojo == null) { return Result.err(ResultCodeEnum.ERROR_PARAM, "參數為空"); } ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); Validator validator = validatorFactory.getValidator(); Set<ConstraintViolation<Object>> constraintViolations = validator.validate(pojo); if (CollUtil.isNotEmpty(constraintViolations)) { return Result.err(ResultCodeEnum.ERROR_PARAM, constraintViolations.iterator().next().getMessage()); } return Result.success(); } }
當針對為數不多的對象來校驗,發現不出來性能問題。但是,當達到上面的8000多條數據時,那性能可以差太多了。
細看控制台列印出來的log,可見一斑。
問題出在 validatorFactory 和 validator 這兩個局部對象的初始化上。尤其是初始化 validatorFactory調用Validation#buildDefaultValidatorFactory, 這個方法內部會涉及到xml文件的讀取和類映射,可見,每次都做這個事情,CPU表示很無辜!
問題即答案————>優化方案是將這2個對象的初始化放在類初始化時。
當看到一些不好的代碼時,會發現我還算優秀;當看到優秀的代碼時,也才意識到持續學習的重要!--buguge
本文來自博客園,轉載請註明原文鏈接:https://www.cnblogs.com/buguge/p/16995017.html