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.

  10. ravi
    August 9th, 2013 at 05:14 | #10

    hi… I m facing a problem in this…
    I have made a JSP page i.e ..
    //register.jsp

     
    REGISTERED SUCCESSFULLY!!!
     

    made a java file..

    // register.java

    package src;

    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.sql.*;
    /**
    *
    * @author gurmeet
    */
    public class register extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType(“text/html;charset=UTF-8″);
    PrintWriter out = response.getWriter();

    /*
    * TODO output your page here. You may use following sample code.
    */
    out.println(“”);
    out.println(“”);
    out.println(“Servlet register”);
    out.println(“”);
    out.println(“”);
    out.println(“Servlet register at ” + request.getContextPath() + “”);

    String name=request.getParameter(“name”);
    String password=request.getParameter(“password”);
    String cpassword=request.getParameter(“cpassword”);
    String squestion=request.getParameter(“squestion”);
    String sanswer=request.getParameter(“sanswer”);
    String email=request.getParameter(“email”);
    String phone=request.getParameter(“phone”);
    try{

    Connection conn= Connect.getConnect();
    Statement smt=conn.createStatement();
    String query=”insert into newuser values(‘”+name+”‘,’”+password+”‘,’”+cpassword+”‘,’”+squestion+”‘,’”+sanswer+”‘,’”+email+”‘,”+phone+”)”;
    smt.executeUpdate(query);
    response.sendRedirect(“register.jsp”);

    out.println(“”);
    out.println(“”);
    }
    catch(Exception obj)
    {
    out.print(obj.getMessage());
    }
    finally {
    out.close();
    }
    }

    //
    /**
    * Handles the HTTP
    * GET method.
    *
    * @param request servlet request
    * @param response servlet response
    * @throws ServletException if a servlet-specific error occurs
    * @throws IOException if an I/O error occurs
    */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    /**
    * Handles the HTTP
    * POST method.
    *
    * @param request servlet request
    * @param response servlet response
    * @throws ServletException if a servlet-specific error occurs
    * @throws IOException if an I/O error occurs
    */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    /**
    * Returns a short description of the servlet.
    *
    * @return a String containing servlet description
    */
    @Override
    public String getServletInfo() {
    return “Short description”;
    }//
    }

    and created a table with following fields..

    CREATE TABLE newuser (
    name char(22),
    password char(21),
    cpassword char(21),
    squestion char(22),
    sanswer char(12),
    email char(50),
    phone number(11),
    CONSTRAINT newuser_pk PRIMARY KEY (name)
    ) ;

    and connected it using …

    //Connect.java

    /*
    * To change this template, choose Tools | Templates
    * and open the template in the editor.
    */
    package src;

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.*;
    public class Connect
    {
    public static Connection getConnect()throws Exception

    {

    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());

    return DriverManager.getConnection(
    “jdbc:oracle:thin:@localhost:1521:XE”, “system”, “1234″);
    }

    }

  11. ravi
    August 9th, 2013 at 06:09 | #11

    // login.java

    /*
    * To change this template, choose Tools | Templates
    * and open the template in the editor.
    */
    package src;

    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.sql.*;
    import javax.servlet.http.HttpSession;

    public class login extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType(“text/html;charset=UTF-8″);
    PrintWriter out = response.getWriter();
    try {
    Connection con = Connect.getConnect();
    String str=request.getParameter(“name”);
    String str1=request.getParameter(“password”);
    HttpSession session = request.getSession(true);
    Statement statement=con.createStatement();
    String query=”select * from newuser where name=’”+str+”‘and password=’”+str1+”‘”;
    ResultSet x=statement.executeQuery(query);
    if(x.next()==true)
    {

    session.setAttribute(“ins1″,str);
    response.sendRedirect(“index.jsp”);
    }
    else
    {
    response.sendRedirect(“invalidu.jsp”);
    }
    }
    catch(Exception obj)
    {
    out.print(obj.getMessage());
    }
    out.println(“”);
    out.println(“”);
    out.println(“Servlet login”);
    out.println(“”);
    out.println(“”);
    out.println(“Servlet login at ” + request.getContextPath() + “”);
    out.println(“”);
    out.println(“”);

    }

    //
    /**
    * Handles the HTTP
    * GET method.
    *
    * @param request servlet request
    * @param response servlet response
    * @throws ServletException if a servlet-specific error occurs
    * @throws IOException if an I/O error occurs
    */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    /**
    * Handles the HTTP
    * POST method.
    *
    * @param request servlet request
    * @param response servlet response
    * @throws ServletException if a servlet-specific error occurs
    * @throws IOException if an I/O error occurs
    */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    /**
    * Returns a short description of the servlet.
    *
    * @return a String containing servlet description
    */
    @Override
    public String getServletInfo() {
    return “Short description”;
    }//
    }

    // login.jsp

    Login

    window.history.forward(1); /*to disable back button*/

    function validate(form)
    {
    if (form.name.value==”")
    { alert(“Name should not be blank. Please enter it.”);
    form.name.focus(); return false;
    }

    re = /^\w+$/;
    if(!re.test(form.name.value))
    {
    alert(“Username must contain only letters, numbers and underscores!”);
    return false;
    }
    var z=form.password.value
    if(z.length < 5)
    {
    alert(" Your Password must be atleast 5 characters ");
    return false;
    }

    if (form.password.value=="")
    { alert("password should not be blank. Please enter it.");
    form.password.focus(); return false;
    }

    if (form.cpassword.value=="")
    { alert("cpassword should not be blank. Please enter it.");
    form.cpassword.focus(); return false;
    }

    }

     

    WELCOME TO LOGIN FORM

    LOGIN ID
    PASSWORD
     

    New User Sign In

  12. ravi
    August 9th, 2013 at 06:19 | #12

    lohin.jsp again…

    Login

    window.history.forward(1); /*to disable back button*/

    function validate(form)
    {
    if (form.name.value==”")
    { alert(“Name should not be blank. Please enter it.”);
    form.name.focus(); return false;
    }

    re = /^\w+$/;
    if(!re.test(form.name.value))
    {
    alert(“Username must contain only letters, numbers and underscores!”);
    return false;
    }
    var z=form.password.value
    if(z.length < 5)
    {
    alert(" Your Password must be atleast 5 characters ");
    return false;
    }

    if (form.password.value=="")
    { alert("password should not be blank. Please enter it.");
    form.password.focus(); return false;
    }

    if (form.cpassword.value=="")
    { alert("cpassword should not be blank. Please enter it.");
    form.cpassword.focus(); return false;
    }

    }

     

    WELCOME TO LOGIN FORM

    LOGIN ID
    PASSWORD
     

    New User Sign In

  13. ravi
    August 9th, 2013 at 06:44 | #13

    Login

    window.history.forward(1); /*to disable back button*/

    function validate(form)
    {
    if (form.name.value==”")
    { alert(“Name should not be blank. Please enter it.”);
    form.name.focus(); return false;
    }

    re = /^\w+$/;
    if(!re.test(form.name.value))
    {
    alert(“Username must contain only letters, numbers and underscores!”);
    return false;
    }
    var z=form.password.value
    if(z.length < 5)
    {
    alert(" Your Password must be atleast 5 characters ");
    return false;
    }

    if (form.password.value=="")
    { alert("password should not be blank. Please enter it.");
    form.password.focus(); return false;
    }

    if (form.cpassword.value=="")
    { alert("cpassword should not be blank. Please enter it.");
    form.cpassword.focus(); return false;
    }

    }

     

    WELCOME TO LOGIN FORM

    LOGIN ID
    PASSWORD
     

    New User Sign In

  14. ravi
    August 9th, 2013 at 06:46 | #14

    login part 1::::

    Login

    window.history.forward(1); /*to disable back button*/

    function validate(form)
    {
    if (form.name.value==”")
    { alert(“Name should not be blank. Please enter it.”);
    form.name.focus(); return false;
    }

  15. ravi
    August 9th, 2013 at 07:22 | #15

     

    WELCOME TO LOGIN FORM

    LOGIN ID
    PASSWORD
     

    New User Sign In

  16. ravi
    August 9th, 2013 at 07:25 | #16

    /*

    Login

    window.history.forward(1); /*to disable back button*/

    function validate(form)
    {
    if (form.name.value==”")
    { alert(“Name should not be blank. Please enter it.”);
    form.name.focus(); return false;
    }

    re = /^\w+$/;
    if(!re.test(form.name.value))
    {
    alert(“Username must contain only letters, numbers and underscores!”);
    return false;
    }
    var z=form.password.value
    if(z.length < 5)
    {
    alert(" Your Password must be atleast 5 characters ");
    return false;
    }

    if (form.password.value=="")
    { alert("password should not be blank. Please enter it.");
    form.password.focus(); return false;
    }

    if (form.cpassword.value=="")
    { alert("cpassword should not be blank. Please enter it.");
    form.cpassword.focus(); return false;
    }

    }

     

    WELCOME TO LOGIN FORM

    LOGIN ID
    PASSWORD
     

    New User Sign In

    */

  17. ravi
    August 9th, 2013 at 07:32 | #17

    WELCOME TO LOGIN FORM

    LOGIN ID
    PASSWORD
     

    New User Sign In

  18. ravi
    August 9th, 2013 at 07:57 | #18

    Untitled Document

  19. ravi
    August 9th, 2013 at 08:03 | #19

    // bus.java

    package src;

    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.sql.*;
    import java.util.Properties;
    import javax.mail.Message;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import javax.servlet.http.HttpSession;

    /**
    *
    * @author gurmeet
    */
    public class bus extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType(“text/html;charset=UTF-8″);
    PrintWriter out = response.getWriter();

    out.println(“”);
    out.println(“”);
    out.println(“Servlet Bus”);
    out.println(“”);
    out.println(“”);
    HttpSession session = request.getSession(true);
    if(session.getAttribute(“ins1″)!=null)
    {
    String bid=”";
    String fro=request.getParameter(“fro”);
    String too=request.getParameter(“too”);
    String journ=request.getParameter(“journ”);
    String no=request.getParameter(“no”).trim();
    int n=Integer.parseInt(no);
    String crno=request.getParameter(“crno”);
    String bank=request.getParameter(“select”);

    String amount=(request.getParameter(“amount”)).trim();
    int a=n*(Integer.parseInt(amount));
    String pay=”Credit card”;
    String name=request.getParameter(“name”);
    String email=request.getParameter(“email”);
    String phone=request.getParameter(“phone”);
    try
    {

    Connection con= Connect.getConnect();

    Statement smt=con.createStatement();
    String qu=”select * from creditcard where bank_name=’”+bank+”‘ and credit_card_no=’”+crno+”‘”;
    int u=0;
    ResultSet rs10=smt.executeQuery(qu);
    while(rs10.next())
    {
    u++;
    }
    if (u>0)
    {

    int c=0;
    try{
    ResultSet rs1=smt.executeQuery(“select sum(no) from bus where fro=’”+fro+”‘ and too=’”+too+”‘ and journ=’”+journ+”‘”);

    while(rs1.next())
    {
    c=Integer.parseInt(rs1.getString(1));
    }
    }
    catch(Exception obj)
    {}
    int count=c+n;
    if(count>30)
    {int seat=count-30;
    int p=n-seat;
    response.sendRedirect(“bus_2.jsp?bid=”+p);
    }
    else{
    ResultSet rs=smt.executeQuery(“select * from bus”);
    int h=0;
    while(rs.next())
    {
    h++;
    }
    bid=”B00″+(h+1);

    String query=”insert into bus values(‘”+fro+”‘,’”+too+”‘,’”+journ+”‘,”+no+”,’”+crno+”‘,’”+pay+”‘,’”+a+”‘,’”+name+”‘,’”+email+”‘,”+phone+”,’Not confirmed’,'”+bid+”‘)”;
    smt.executeUpdate(query);
    response.sendRedirect(“bus_1.jsp?bid=”+bid);
    }
    }
    else
    {
    out.print(“Invalid Credit Card Details”);
    }

    }

    catch(Exception obj)
    {
    out.print(obj.getMessage());
    }
    finally {
    out.close();
    }

    out.println(“Servlet trains at ” + request.getContextPath() + “”);
    out.println(“”);
    out.println(“”);

    //code for sending mail
    String host=”pop.gmail.com”,user=”", pass=”";

    user=”chetnasaxena91@gmail.com”;
    pass=”japneet321″;
    //host = smtp_server; //”smtp.gmail.com”; user = jsp_email; //”YourEmailId@gmail.com” // email id to send the emails
    //pass = jsp_email_pw; //Your gmail password
    String SSL_FACTORY = “javax.net.ssl.SSLSocketFactory”;
    String to =email; // out going email id
    String from = “chetnasaxena91@gmail.com”; //Email id of the recipient
    String subject = “Booking Details”;
    String messageText = “Now you can get your E-Ticket,Your Booking Id is”+bid;
    boolean sessionDebug = true;
    Properties props = System.getProperties();
    props.put(“mail.host”, host);
    props.put(“mail.transport.protocol.”, “smtp”);
    props.put(“mail.smtp.auth”, “true”);
    props.put(“mail.smtp.”, “true”);
    props.put(“mail.smtp.port”, “465″);
    props.put(“mail.smtp.socketFactory.fallback”, “false”);
    props.put(“mail.smtp.socketFactory.class”, SSL_FACTORY);
    Session mailSession = Session.getDefaultInstance(props, null);
    mailSession.setDebug(sessionDebug);
    try{

    Message msg= new MimeMessage(mailSession);
    msg.setFrom(new InternetAddress(from));
    InternetAddress[] address = {new InternetAddress(to)};
    msg.setRecipients(Message.RecipientType.TO, address);
    msg.setSubject(subject);
    msg.setContent(messageText, “text/html”); // use setText if you want to send text

    Transport transport;
    transport = mailSession.getTransport(“smtp”);
    transport.connect(host, user, pass);

    transport.sendMessage(msg, msg.getAllRecipients());
    //WasEmailSent = true; // assume it was sent
    transport.close();}
    catch (Exception err) {
    //WasEmailSent = false; // assume it’s a fail
    }

    }
    else
    {
    response.sendRedirect(“nuser.jsp”);
    }

    }

    //
    /**
    * Handles the HTTP
    * GET method.
    *
    * @param request servlet request
    * @param response servlet response
    * @throws ServletException if a servlet-specific error occurs
    * @throws IOException if an I/O error occurs
    */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    /**
    * Handles the HTTP
    * POST method.
    *
    * @param request servlet request
    * @param response servlet response
    * @throws ServletException if a servlet-specific error occurs
    * @throws IOException if an I/O error occurs
    */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    processRequest(request, response);
    }

    /**
    * Returns a short description of the servlet.
    *
    * @return a String containing servlet description
    */
    @Override
    public String getServletInfo() {
    return “Short description”;
    }//
    }

  20. ravi
    August 9th, 2013 at 09:22 | #20

    //

    register
    src.register

    bus
    src.bus

    trains
    src.trains

    air
    src.air

    packages
    src.packages

    adminlog
    src.adminlog

    login
    src.login

    hotel
    src.hotel

    register
    /register/*

    trains
    /trains/*

    bus
    /bus/*

    air
    /air/*

    packages
    /packages/*

    adminlog
    /adminlog/*

    hotel
    /hotel/*

    login
    /login/*

    30

  21. ravi
    August 9th, 2013 at 09:56 | #21

    // context.xml

  22. ravi
    August 9th, 2013 at 09:56 | #22
  23. July 15th, 2014 at 00:12 | #23

    Someone necessarily assist to make seriously articles I’d state. This is the first time I frequented your website page and to this point? I surprised with the research you made to create this actual put up amazing. Excellent activity!

  1. October 11th, 2014 at 07:19 | #1
  2. October 12th, 2014 at 15:05 | #2
  3. October 12th, 2014 at 22:22 | #3
  4. October 13th, 2014 at 22:51 | #4
  5. October 14th, 2014 at 04:02 | #5
  6. October 14th, 2014 at 12:44 | #6
  7. October 15th, 2014 at 23:07 | #7
  8. October 16th, 2014 at 22:32 | #8
  9. October 17th, 2014 at 01:12 | #9
  10. October 18th, 2014 at 12:23 | #10