是否有正确的方法在slf4j中传递参数?

时间:2011-08-18 04:23:13

标签: java 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);

这是记录痕迹的首选机制。

3 个答案:

答案 0 :(得分:49)

3是最好的。

3和2生成相同(或几乎相同)的字节码,但3更容易键入并且更短,因此3优于2.

如果未启用跟踪,则1必须执行字符串连接(“存储时间”+计数+ ....)这有点贵,而2仅在启用跟踪时才执行字符串连接,这就是为什么3优于1。

答案 1 :(得分:29)

3是最好的,除了SLF4J 1.6.x不支持它。对于三个或更多参数,您需要第二个表单。第三种形式仅适用于一个或两个参数(但不是三个或更多)。

从SLF4J 1.7开始,第三种形式现在也支持3个或更多参数。 java编译器将具有3个或更多参数的调用静默转换为第二个表单,将Object []传递给打印方法。这是Java中varargs的实现细节,允许SLF4J 1.7与SLF4J 1.6 100%兼容。

答案 2 :(得分:7)

第三种变体是最好的变体。

实际上,第一种情况是通过StringBuilder进行字符串连接。

第二和第三个案例是相同的。 他们需要将整数值设置为Integer(或其他Object),然后创建一个数组来打包它们。

我机器上的简单测试表明,如果没有执行任何记录,第三种变体在大约8次中会更好(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);
    }
}