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

Java 在slf4j中是否有传递参数的正确方法?,java,slf4j,Java,Slf4j,Im使用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 {} obj

Im使用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是最好的

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


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

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


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

第三种变体是最好的

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

第2例和第3例是相同的。 他们需要将整数值框到整数(或其他对象),然后创建一个数组来打包它们

在我的机器上进行的简单测试表明,如果不执行日志记录(56ns vs 459ns),第三种变体的性能会提高大约8倍

公共类日志测试{
私有静态最终记录器Logger=LoggerFactory.getLogger(LogTest.class);
公共静态void main(字符串[]args){
int size=100_000_000;
长启动=System.nanoTime();
对于(int i=0;i
3不编译。但是,varargs语法允许3(如果我理解正确的话)。如果这是一个真正的紧密循环,并且性能至关重要,那么该错误报告将在
If(log.isTraceEnabled())中包装log命令{…
statement你知道这是否仍然是真的吗。我在JMH上读了下面的博客,它让我好奇:这篇文章很好。我不认为这篇文章与上述内容相矛盾,也就是说,构建Object[]的成本降低了,问题也就小了。@SergeyLeyko为新版本的slf4j编译。
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);
    }
}