66

Im using slf4j for tracing the information. My code is

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

Which would be the preferred mechanism to log traces.

2
  • 3
    3 does not compile. The varargs syntax would allow 3 however (if I understand it correctly). The bug report for that is at bugzilla.slf4j.org/show_bug.cgi?id=31 Commented Jan 18, 2012 at 7:59
  • 1
    If that's a real tight loop, and performance is critical, you should wrap the log command in if (log.isTraceEnabled()) {... statement Commented Apr 25, 2015 at 11:47

3 Answers 3

69

3 is the best.

3 and 2 generate the same (or nearly the same) bytecode, but 3 is easier to type and is shorter, so 3 is better than 2.

If trace is not enabled, 1 must perform string concatenation ("Time taken to store " + count + ....) which is somewhat expensive, while 2 does the string concatenation only if trace is enabled, which is why 3 is better than 1.

Sign up to request clarification or add additional context in comments.

1 Comment

@SergeyLeyko Compiles for newer version of slf4j.
32

3 is best except that it is not supported in SLF4J 1.6.x. For three or more arguments you need the second form. The third form only works with one or two arguments (but not three or more).

As of SLF4J 1.7, the third form is now supported for 3 or more arguments as well. The java compiler silently transforms invocations with 3 or more arguments to the second form, passing an Object[] to the printing method. This is an implementation detail of varargs in Java and allows SLF4J 1.7 to be 100% compatible with SLF4J 1.6.

2 Comments

do you know if this is still true. I was reading the following blog on JMH and it made me curious: antoniogoncalves.org/2015/01/15/…
Nice article. I don't think that the article contradicts the above, i.e. the cost of constructing Object[] has decreased and is merely less of an issue.
9

The 3rd variant is the best one.

In fact 1st case is a string concatenation via StringBuilder.

The 2nd and 3rd cases are the same. They need to box integer values to Integer (or other Object) and then to create an array to pack them.

The simple test on my machine say that the 3rd variant is better in about 8 times in case if no logging executed (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);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.