Home > java > System.out.println performance

System.out.println performance

November 10th, 2010 Leave a comment Go to comments

Any system that logs vast amounts of information, needs to think about performance. The activity of logging cannot be a synchronous blocking call that returns only when the message has been logged to a persistence store. Enterprise logging systems usually make use of a message bus to carry messages asynchronously to their target persistence store. Be it a database or a file.

Talking about logging brings us to System.out.println() (Lets call is SOP for short). It is a surprisingly commonly method to “log” messages. SOP is not meant to be used as a logging system, but unfortunately there is no dearth of projects that have these statements scattered around the code base. The adverse effects that this statement can bring on the performance of the system is often not recognized as well as it should be.

Why is SOP a bottleneck for performance ? This is why…

Code excerpt from PrintStream.java:

    private void write(String s)
    {
        try
        {
            synchronized (this)
            {
                ensureOpen();
                textOut.write(s);
                textOut.flushBuffer();
                charOut.flushBuffer();
                if (autoFlush && (s.indexOf('\n') >= 0))
                    out.flush();
            }
        }
        catch (InterruptedIOException x)
        {
            Thread.currentThread().interrupt();
        }
        catch (IOException x)
        {
            trouble = true;
        }
    }

All SOP calls on a String result in a corresponding call to the private write(String s) method in PrintStream.java. The synchronized block ensures that every thread has to wait for this call to end before it can proceed. Whats more, the calls to flushBuffer() on the BufferedWriter that is textOut result in the execution of more synchronized blocks. These blocks are expensive to execute.

Here is a chart that shows how performance degrades when a program logs 100,000 messages through various threads. The rate of degradation also depends on the number of characters that are passing through the stream.

System.out.println performance:
System.out.println performance

The degradation experienced in ‘Web application X / Y’ may vary, but it cannot be discounted. Avoid using SOPs to log messages in your app. Even one or two that are left over can harm performance under the right conditions. Let us also not forget about e.printStackTrace() and other forms of writing to console output that follow the same synchronized pattern.





Categories: java Tags: ,
  1. jbb
    November 10th, 2010 at 16:28 | #1

    But what should be use to log then ? Finaly, it must ends with a SOP …

  2. IBBoard
    November 11th, 2010 at 09:29 | #2

    @jbb: How about a logging framework? Something like Log4J lets you do formatting, logging levels, output level configuration, and multiple output destinations. If *it* uses SOP in a sync block then it is badly written, but as a logging framework then it should be able to do async queueing and logging.

    I’ve got in to the habit of avoiding SOP (and C#’s Console.WriteLine) except where absolutely necessary (i.e. quick hack debugging of libraries that don’t want Log4Net as a dependency – code which is later removed). If you’ve got a library and don’t want to include a logging dependency then you should be throwing exceptions – SOP may print messages people can read, but it also prints messages that people can ignore and is about as useful from a library as a catch with the comment “hide exception”, IMO.

  3. November 12th, 2010 at 06:19 | #3

    I am interested to know what tool you used to come up with that graph. :)

  4. November 12th, 2010 at 07:36 | #4

    same here what tool you used for graph

  5. November 12th, 2010 at 11:12 | #5

    how can we view the logs in this help me out

  6. November 12th, 2010 at 17:21 | #6

    @jbb
    @IBBoard

    My guess is that a system like log4j would allow for asynchronous logging. Logg4j allows you to configure a couple of appenders. It would be crazy if log4j tried to write to all appenders before returning.

    @Jeune
    @neo

    Thanks :D The graph was created using, can you believe it, google chart. Thank you Google.

    I am not sure I caught you comment on the logs neo. The logs generated by the program are not displayed anywhere in the post. Only the performance graph based on the log timings was charted.

  7. RobG
    November 13th, 2010 at 12:40 | #7

    @IBBoard

    If you have a library and are afraid of dependencies, why not use the JDK logger?

  8. February 4th, 2011 at 06:07 | #8

    Yes JDK logger is better than log4j for most of the application but not everyone is aware of its presence in the JDK :(

    http://extreme-java.blogspot.com

  9. February 6th, 2011 at 16:15 | #9

    True. Logging should be used sparingly.

  1. No trackbacks yet.