2011-08-18 10 views
29

Im usando slf4j per tracciare le informazioni. Il mio codice èEsiste un modo corretto per passare argomenti in 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); 

Quale sarebbe il meccanismo preferito per registrare le tracce.

+0

Il secondo. –

+1

3 non viene compilato. La sintassi varargs consentirebbe comunque 3 (se ho capito bene). Il bug report per questo è su http://bugzilla.slf4j.org/show_bug.cgi?id=31 –

+1

Se si tratta di un vero e proprio anello chiuso, e le prestazioni sono critiche, dovresti racchiudere il comando log in 'if (log.isTraceEnabled()) {... 'la dichiarazione – Yonatan

risposta

34

3 è il migliore.

3 e 2 generano lo stesso (o quasi lo stesso) bytecode, ma 3 è più facile da digitare ed è più corto, quindi 3 è meglio 2.

Se la traccia non è abilitata, 1 deve eseguire stringa concatenazione ("Tempo necessario per memorizzare" + contare + ....) che è un po 'costoso, mentre 2 fa la concatenazione di stringhe solo se la traccia è abilitata, motivo per cui 3 è migliore di 1.

+0

ha corretto la mia risposta, ottenuto 3 e 2 mescolati – sbridges

+3

3 non compilato. –

26

3 è il migliore tranne che non è supportato in SLF4J 1.6.x. Per tre o più argomenti è necessario il secondo modulo. Il terzo modulo funziona solo con uno o due argomenti (ma non tre o più).

A partire da SLF4J 1.7, il terzo modulo è ora supportato anche per 3 o più argomenti. Il compilatore java trasforma silenziosamente le invocazioni con 3 o più argomenti nel secondo modulo, passando un oggetto [] al metodo di stampa. Questo è un dettaglio di implementazione di vararg in Java e consente a SLF4J 1.7 di essere compatibile al 100% con SLF4J 1.6.

+1

sai se questo è ancora vero. Stavo leggendo il seguente blog su JMH e questo mi ha incuriosito: http://antoniogoncalves.org/2015/01/15/micro-benchmarking-with-jmh-measure-dont-guess/ – Ole

+0

Bel articolo. Non penso che l'articolo contraddica quanto sopra, cioè il costo della costruzione di Object [] è diminuito ed è semplicemente meno di un problema. – Ceki

6

La terza variante è la migliore.

In effetti, il primo caso è una concatenazione di stringhe tramite StringBuilder.

Il 2 ° e il 3 ° caso sono uguali. Devono inserire valori interi a numero intero (o altro oggetto) e quindi creare una matrice per comprimerli.

Il semplice test sulla mia macchina indica che la terza variante è migliore in circa 8 volte nel caso in cui non venga eseguita alcuna registrazione (56ns vs 459ns).

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); 
    } 
} 
Problemi correlati