Java日誌格式應該是佔位符仍是字符串拼接

背景

​ 上次在羣中,有個羣友說本身把全部項目中,全部使用佔位符打印日誌的方式都修改爲爲了字符串拼接的方式,由於他曾經看了一篇文章,說字符串拼接的形式比佔位符形式的性能更好,這個話題引發了你們的普遍討論。java

​ 在我印象中,我記得曾經看過的文章說,佔位符的方式性能好,由於若是不打日誌的話,就不會進行字符串拼接,節省性能。最後抱着一探究竟的心態,我進行了一第二天志輸出方式的實驗。git

工具

IDEA + Gradle + JDK 8 + SpringBoot + Junit + Slf4j + logbackgithub

測試方式

本次測試我定義了4個方法,每一個方法同時打印 DEBUG ,INFO 日誌,默認日誌級別是INFO級別的,全部DEBUG級別日誌是不輸出的,這樣能夠檢測輸出的日誌會不會被不輸出級別日誌影響,同時我還給部分方法增長了if判斷,這個是爲了測試,咱們是否有必要顯性的進行日誌級別的操做,具體代碼以下:spring

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測試用例,結果以下:微信

結論

經過測試結果能夠有如下發現:spring-boot

字符串拼接的方法,大部分下狀況性能高於佔位符工具

若是採用佔位符的方式,必定不要增長 log.isDebugEnabled()這種方式再顯性的進行判斷,不然性能會大大下降性能

昨天看到nacos項目,在翻看nacos源碼的時候,發現針對日誌輸出這塊,nacos也使用的字符串拼接測試

本文沒有過高深的道理和原理,只是由於一個小的討論,進行了一次實驗,實驗的過程和結果是否準確可靠還須要你們各自斟酌,同時但願藉此拋磚引玉,能有大神給更加詳細的解答。url

github地址: https://github.com/Shiyajian/examples ,查看 spring-boot/chapter1/log

其餘

本身寫了個插件,能夠打開CSDN的博客以後,自動展開所有內容,不用每次點【查看更多】,而後還須要登陸那麼麻煩了,github: https://github.com/Shiyajian/CSDN-clear.git

我的QQ好友羣:757696438,吹牛扯淡爲主,技術爲輔,拒絕裝逼,最歡迎妹子。 我的微信:q408859832 技術交流爲主 備註:博客園

相關文章
相關標籤/搜索