< prev index next >

src/java.base/share/classes/java/io/PrintStream.java

Print this page
rev 53030 : 8215412: Optimize PrintStream.println methods
Reviewed-by: core-libs

@@ -63,10 +63,11 @@
 public class PrintStream extends FilterOutputStream
     implements Appendable, Closeable
 {
 
     private final boolean autoFlush;
+    private final boolean internal;
     private boolean trouble = false;
     private Formatter formatter;
 
     /**
      * Track both the text- and character-output streams, so that their buffers

@@ -105,14 +106,19 @@
 
     /* Private constructors */
     private PrintStream(boolean autoFlush, OutputStream out) {
         super(out);
         this.autoFlush = autoFlush;
+        this.internal = isInternal();
         this.charOut = new OutputStreamWriter(this);
         this.textOut = new BufferedWriter(charOut);
     }
 
+    private final boolean isInternal() {
+        return this.getClass().getModule() == PrintStream.class.getModule();
+    }
+
     /* Variant of the private constructor so that the given charset name
      * can be verified before evaluating the OutputStream argument. Used
      * by constructors creating a FileOutputStream that also take a
      * charset name.
      */

@@ -189,10 +195,11 @@
      * @since  10
      */
     public PrintStream(OutputStream out, boolean autoFlush, Charset charset) {
         super(out);
         this.autoFlush = autoFlush;
+        this.internal = isInternal();
         this.charOut = new OutputStreamWriter(this, charset);
         this.textOut = new BufferedWriter(charOut);
     }
 
     /**

@@ -573,11 +580,11 @@
      * The following private methods on the text- and character-output streams
      * always flush the stream buffers, so that writes to the underlying byte
      * stream occur as promptly as with the original PrintStream.
      */
 
-    private void write(char buf[]) {
+    private void write(char[] buf) {
         try {
             synchronized (this) {
                 ensureOpen();
                 textOut.write(buf);
                 textOut.flushBuffer();

@@ -586,10 +593,28 @@
                     for (int i = 0; i < buf.length; i++)
                         if (buf[i] == '\n')
                             out.flush();
                 }
             }
+        } catch (InterruptedIOException x) {
+            Thread.currentThread().interrupt();
+        } catch (IOException x) {
+            trouble = true;
+        }
+    }
+
+    private void writeln(char[] buf) {
+        try {
+            synchronized (this) {
+                ensureOpen();
+                textOut.write(buf);
+                textOut.newLine();
+                textOut.flushBuffer();
+                charOut.flushBuffer();
+                if (autoFlush)
+                    out.flush();
+            }
         }
         catch (InterruptedIOException x) {
             Thread.currentThread().interrupt();
         }
         catch (IOException x) {

@@ -614,10 +639,30 @@
         catch (IOException x) {
             trouble = true;
         }
     }
 
+    private void writeln(String s) {
+        try {
+            synchronized (this) {
+                ensureOpen();
+                textOut.write(s);
+                textOut.newLine();
+                textOut.flushBuffer();
+                charOut.flushBuffer();
+                if (autoFlush)
+                    out.flush();
+            }
+        }
+        catch (InterruptedIOException x) {
+            Thread.currentThread().interrupt();
+        }
+        catch (IOException x) {
+            trouble = true;
+        }
+    }
+
     private void newLine() {
         try {
             synchronized (this) {
                 ensureOpen();
                 textOut.newLine();

@@ -778,113 +823,145 @@
      * {@link #println()}.
      *
      * @param x  The {@code boolean} to be printed
      */
     public void println(boolean x) {
+        if (internal) {
+            writeln(String.valueOf(x));
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints a character and then terminate the line.  This method behaves as
      * though it invokes {@link #print(char)} and then
      * {@link #println()}.
      *
      * @param x  The {@code char} to be printed.
      */
     public void println(char x) {
+        if (internal) {
+            writeln(String.valueOf(x));
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints an integer and then terminate the line.  This method behaves as
      * though it invokes {@link #print(int)} and then
      * {@link #println()}.
      *
      * @param x  The {@code int} to be printed.
      */
     public void println(int x) {
+        if (internal) {
+            writeln(String.valueOf(x));
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints a long and then terminate the line.  This method behaves as
      * though it invokes {@link #print(long)} and then
      * {@link #println()}.
      *
      * @param x  a The {@code long} to be printed.
      */
     public void println(long x) {
+        if (internal) {
+            writeln(String.valueOf(x));
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints a float and then terminate the line.  This method behaves as
      * though it invokes {@link #print(float)} and then
      * {@link #println()}.
      *
      * @param x  The {@code float} to be printed.
      */
     public void println(float x) {
+        if (internal) {
+            writeln(String.valueOf(x));
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints a double and then terminate the line.  This method behaves as
      * though it invokes {@link #print(double)} and then
      * {@link #println()}.
      *
      * @param x  The {@code double} to be printed.
      */
     public void println(double x) {
+        if (internal) {
+            writeln(String.valueOf(x));
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints an array of characters and then terminate the line.  This method
      * behaves as though it invokes {@link #print(char[])} and
      * then {@link #println()}.
      *
      * @param x  an array of chars to print.
      */
-    public void println(char x[]) {
+    public void println(char[] x) {
+        if (internal) {
+            writeln(x);
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints a String and then terminate the line.  This method behaves as
      * though it invokes {@link #print(String)} and then
      * {@link #println()}.
      *
      * @param x  The {@code String} to be printed.
      */
     public void println(String x) {
+        if (internal) {
+            writeln(x);
+        } else {
         synchronized (this) {
             print(x);
             newLine();
         }
     }
+    }
 
     /**
      * Prints an Object and then terminate the line.  This method calls
      * at first String.valueOf(x) to get the printed object's string value,
      * then behaves as

@@ -893,15 +970,21 @@
      *
      * @param x  The {@code Object} to be printed.
      */
     public void println(Object x) {
         String s = String.valueOf(x);
+        if (internal) {
+            // need to do String.valueOf(s) since String.valueOf(x)
+            // might return null
+            writeln(String.valueOf(s));
+        } else {
         synchronized (this) {
             print(s);
             newLine();
         }
     }
+    }
 
 
     /**
      * A convenience method to write a formatted string to this output stream
      * using the specified format string and arguments.
< prev index next >