2011-08-18 17 views
29

Estoy usando slf4j para rastrear la información. Mi código es¿Hay una forma correcta de pasar argumentos en 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); 

Cuál sería el mecanismo preferido para registrar las huellas.

+0

El segundo. –

+1

3 no compila. La sintaxis varargs permitiría 3 sin embargo (si lo entiendo correctamente). El informe de error para eso está en http://bugzilla.slf4j.org/show_bug.cgi?id=31 –

+1

Si se trata de un bucle estrecho real, y el rendimiento es crítico, debe ajustar el comando de registro en 'if (log.isTraceEnabled()) {... 'declaración – Yonatan

Respuesta

34

3 es el mejor.

3 y 2 generan el mismo (o casi el mismo) código de bytes, pero 3 es más fácil de escribir y es más corta, por lo que es mejor que 3 2.

Si traza no está habilitado, 1 debe realizar la concatenación de cadenas ("Tiempo necesario para almacenar" + conteo + ....) que es algo costoso, mientras que 2 realiza la concatenación de cadenas solo si el rastreo está habilitado, razón por la cual 3 es mejor que 1.

+0

corrigió mi respuesta, obtuvo 3 y 2 confundido – sbridges

+3

3 no compila. –

26

3 es mejor excepto que no es compatible con SLF4J 1.6.x. Para tres o más argumentos necesita la segunda forma. La tercera forma solo funciona con uno o dos argumentos (pero no tres o más).

A partir de SLF4J 1.7, la tercera forma ahora es compatible con 3 o más argumentos también. El compilador de Java transforma silenciosamente invocaciones con 3 o más argumentos en el segundo formulario, pasando un Objeto [] al método de impresión. Este es un detalle de implementación de varargs en Java y permite que SLF4J 1.7 sea 100% compatible con SLF4J 1.6.

+1

¿sabes si esto sigue siendo cierto? Estaba leyendo el siguiente blog en JMH y me dio curiosidad: http://antoniogoncalves.org/2015/01/15/micro-benchmarking-with-jmh-measure-dont-guess/ – Ole

+0

Buen artículo. No creo que el artículo contradiga lo anterior, es decir, el costo de construir Objeto [] ha disminuido y es simplemente un problema menor. – Ceki

6

La tercera variante es la mejor.

De hecho, el primer caso es una cadena de concatenación a través de StringBuilder.

El segundo y el tercer caso son iguales. Necesitan encapsular valores enteros en Integer (u otro objeto) y luego crear una matriz para empaquetarlos.

La prueba simple en mi máquina dice que la 3ra variante es mejor en unas 8 veces en caso de que no se ejecute ningún registro (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); 
    } 
} 
Cuestiones relacionadas