Java日誌格式應該是占位符還是字符串拼接
背景
? 上次在群中,有個群友說自己把所有項目中,所有使用占位符打印日誌的方式都修改成為了字符串拼接的方式,因為他曾經看了一篇文章,說字符串拼接的形式比占位符形式的性能更好,這個話題引起了大家的廣泛討論。
? 在我印象中,我記得曾經看過的文章說,占位符的方式性能好,因為如果不打日誌的話,就不會進行字符串拼接,節省性能。最後抱著一探究竟的心態,我進行了一次日誌輸出方式的實驗。
工具
IDEA + Gradle + JDK 8 + SpringBoot + Junit + Slf4j + logback
測試方式
本次測試我定義了4個方法,每個方法同時打印 DEBUG ,INFO 日誌,默認日誌級別是INFO級別的,所有DEBUG級別日誌是不輸出的,這樣可以檢測輸出的日誌會不會被不輸出級別日誌影響,同時我還給部分方法增加了if判斷,這個是為了測試,我們是否有必要顯性的進行日誌級別的操作,具體代碼如下:
public void record(LogEntity logEntity) { for (int i = 0; i < 1000; i++) { if (log.isDebugEnabled()) { log.debug("id:{},name:{},ip:{},url:{},params:{}", logEntity.getId(), logEntity.getName(), logEntity.getId(), logEntity.getUrl(), logEntity.getParams()); } log.info("id:{},name:{},ip:{},url:{},params:{}", logEntity.getId(), logEntity.getName(), logEntity.getId(), logEntity.getUrl(), logEntity.getParams()); } } public void record1(LogEntity logEntity) { for (int i = 0; i < 1000; i++) { log.debug("id:{},name:{},ip:{},url:{},params:{}", logEntity.getId(), logEntity.getName(), logEntity.getId(), logEntity.getUrl(), logEntity.getParams()); log.info("id:{},name:{},ip:{},url:{},params:{}", logEntity.getId(), logEntity.getName(), logEntity.getId(), logEntity.getUrl(), logEntity.getParams()); } } public void record2(LogEntity logEntity) { for (int i = 0; i < 1000; i++) { if (log.isDebugEnabled()) { log.debug("id:" + logEntity.getId() + ",name:" + logEntity.getName() + ",ip:" + logEntity.getId() + ",url:" + logEntity.getUrl() + ",params:" + logEntity.getParams()); } log.info("id:" + logEntity.getId() + ",name:" + logEntity.getName() + ",ip:" + logEntity.getId() + ",url:" + logEntity.getUrl() + ",params:" + logEntity.getParams()); } } public void record3(LogEntity logEntity) { for (int i = 0; i < 1000; i++) { log.debug("id:" + logEntity.getId() + ",name:" + logEntity.getName() + ",ip:" + logEntity.getId() + ",url:" + logEntity.getUrl() + ",params:" + logEntity.getParams()); log.info("id:" + logEntity.getId() + ",name:" + logEntity.getName() + ",ip:" + logEntity.getId() + ",url:" + logEntity.getUrl() + ",params:" + logEntity.getParams()); } }
測試結果
我運行了6次Junit測試用例,結果如下:
結論
通過測試結果可以有以下發現:
字符串拼接的方法,大部分下情況性能高於占位符
如果采用占位符的方式,一定不要增加 log.isDebugEnabled()這種方式再顯性的進行判斷,否則性能會大大降低
昨天看到nacos項目,在翻看nacos源碼的時候,發現針對日誌輸出這塊,nacos也使用的字符串拼接
本文沒有太高深的道理和原理,只是因為一個小的討論,進行了一次實驗,實驗的過程和結果是否準確可靠還需要大家各自斟酌,同時希望借此拋磚引玉,能有大神給更加詳細的解答。
github地址: https://github.com/Shiyajian/examples ,查看 spring-boot/chapter1/log
其他
自己寫了個插件,可以打開CSDN的博客之後,自動展開全部內容,不用每次點【查看更多】,然後還需要登錄那麽麻煩了,github: https://github.com/Shiyajian/CSDN-clear.git
個人QQ好友群:757696438,吹牛扯淡為主,技術為輔,拒絕裝逼,最歡迎妹子。
個人微信:q408859832 技術交流為主
備註:博客園
Java日誌格式應該是占位符還是字符串拼接