2011-08-18 45 views
29

使用slf4j來跟蹤信息。我的代碼是在slf4j中傳遞參數是否有正確的方法?

private static final Logger log = LoggerFactory.getLogger(ObjectTest.class); 

log.trace("Time taken to store " + count 
      + " objects of size " + size + " is " + (time) + " msecs"); 

log.trace("Time taken to store {} objects of size {} is {} msecs", 
     new Object[] { count, size, time }); 

log.trace("Time taken to store {} objects of size {} is {} msecs", 
     count, size, time); 

這將是記錄跟蹤的首選機制。

+0

的第二個。 –

+1

3不編譯。然而,可變參數語法將允許3(如果我理解正確)。這個錯誤報告在http://bugzilla.slf4j.org/show_bug.cgi?id=31 –

+1

如果這是一個真正的嚴格循環,並且性能很關鍵,那麼你應該將log命令包裝在if(log.isTraceEnabled ()){...'語句 – Yonatan

回答

34

3是最好的。

3和2產生相同的(或幾乎相同)的字節碼,但圖3是更容易輸入和較短,所以圖3是大於2

如果未啓用跟蹤,1必須執行字符串連接更好(「時間採取存儲」 +數+ ...),這是比較昂貴的,而2只做如果啓用跟蹤字符串連接,這就是爲什麼3比1

+0

糾正我的答案,得到3和2混合起來 – sbridges

+3

3不編譯。 –

26

3較好,例外的是最好的它在SLF4J 1.6.x中不受支持。對於三個或更多的參數,你需要第二種形式。第三種形式只適用於一個或兩個參數(但不是三個或更多)。

作爲SLF4J 1.7的,所述第三形式現在支持3個或多個參數,以及。 java編譯器靜靜地將具有3個或更多參數的調用轉換爲第二種形式,將Object []傳遞給打印方法。這是Java中可變參數的實現細節,允許SLF4J 1.7與SLF4J 1.6完全兼容。

+1

你知不知道這是否仍然如此。我正在閱讀關於JMH的以下博客,這讓我很好奇:http://antoniogoncalves.org/2015/01/15/micro-benchmarking-with-jmh-measure-dont-guess/ – Ole

+0

好文章。我認爲這篇文章與上述內容相矛盾,即構建Object []的成本已經下降,並且僅僅是一個問題。 – Ceki

6

第三個變體是最好的。

事實上,第一種情況是通過StringBuilder進行字符串連接。

第二和第三種情況是相同的。 他們需要將整數值整理到整數(或其他對象),然後創建一個數組來打包它們。

我的機器上的簡單的測試說,如果沒有記錄執行(56ns VS 459ns)第三變異是在約8倍的情況下。

public class LogTest { 
    private static final Logger logger = LoggerFactory.getLogger(LogTest.class); 

    public static void main(String[] args) { 
     int size = 100_000_000; 

     long start = System.nanoTime(); 
     for (int i = 0; i < size; i++) { 
      logger.trace("1 {} 2 {} 3 {}", i, i, i); 
     } 
     System.out.println((System.nanoTime() - start)/size); 

     start = System.nanoTime(); 
     for (int i = 0; i < size; i++) { 
      logger.trace("1 " + i + " 2 " + i + " 3 " + i); 

     } 
     System.out.println((System.nanoTime() - start)/size); 
    } 
} 
相關問題