我正在使用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);
这是记录痕迹的首选机制。
答案 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);
}
}