web-dev-qa-db-fra.com

Existe-t-il un moyen correct de passer des arguments dans slf4j?

Im utilisant slf4j pour retrouver les informations. Mon code est

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);

Quel serait le mécanisme préféré pour consigner les traces.

43
diya

3 est le meilleur.

3 et 2 génèrent le même (ou presque le même) octetecode, mais 3 est plus facile à taper et est plus court, donc 3 vaut mieux que 2.

Si la trace n'est pas activée, 1 doit effectuer la concaténation de chaînes ("Temps nécessaire pour stocker" + nombre + ....) ce qui est un peu cher, tandis que 2 effectue la concaténation de chaînes uniquement si la trace est activée, c'est pourquoi 3 est mieux que 1.

51
sbridges

3 est le meilleur, sauf qu'il n'est pas pris en charge dans SLF4J 1.6.x. Pour trois arguments ou plus, vous avez besoin du deuxième formulaire. Le troisième formulaire ne fonctionne qu'avec un ou deux arguments (mais pas trois ou plus).

Depuis SLF4J 1.7, le troisième formulaire est désormais pris en charge pour 3 arguments ou plus. Le compilateur Java transforme silencieusement les invocations avec 3 arguments ou plus vers le second formulaire, en passant un Object [] à la méthode d'impression. Il s'agit d'un détail d'implémentation de varargs dans Java et permet à SLF4J 1.7 d'être 100% compatible avec SLF4J 1.6.

30
Ceki

La 3ème variante est la meilleure.

En fait, le premier cas est une concaténation de chaînes via StringBuilder.

Les 2e et 3e cas sont les mêmes. Ils doivent encadrer les valeurs entières en entier (ou autre objet), puis créer un tableau pour les emballer.

Le simple test sur ma machine indique que la 3ème variante est meilleure en 8 fois environ si aucune journalisation n'est exécutée (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);
    }
}
7