RFR: 8215412: Optimize PrintStream.println methods

Claes Redestad claes.redestad at oracle.com
Fri Dec 14 20:22:44 UTC 2018


On 2018-12-14 19:06, Roger Riggs wrote:
> Hi Claes,
> 611: Can't the loop break after finding the first \n?

shouldn't have been a loop there at all (and yes, in the pre-existing
version breaking after finding the first \n should be ok)

> 916: I'd probably call writeln(String.valueOf(x)) and skip the extra 
> method call.

We need to call String.valueOf twice in the Object case to deal with
toString() returning null.

That said, concerns was raised that this implementation might change
behavior in code that overrides PrintStream unexpectedly due println
no longer calling the corresponding print method.

I've prepared the work for a CSR to investigate and assess if that
behavior change is too risky, and in the meantime implemented a
version of this optimization that only optimizes println if
PrintStream is defined in java.base:


Same performance characteristics in the simple tests I've used to
verify this, and no measurable regression (but no speed-up) for classes
overriding PrintStream.



> Is there any benefit of doing the String conversions before the 
> synchronized block?
> As is in the old code for println(Object x).
> There isn't much contention I expect so it's probably a benefit, 
> (compared to easy to read code).
> Thanks, Roger
> On 12/14/2018 12:12 PM, Claes Redestad wrote:
>> Hi,
>>  the various PrintStream.println methods are inefficient: nested
>> synchronization, multiple flushes and a scan of the input string for
>> newlines that in the end is pointless in this context since newLine will
>> always flush anyway (if autoflush is enabled).
>>  While performance of printing to console/file is likely to be
>> dominated by the I/O overheads, there are plenty of simple text
>> processing applications using stdout to pipe output to another process
>> for which performance of println could definitely matter.
>> Webrev: http://cr.openjdk.java.net/~redestad/8215412/jdk.00/
>> Bug: https://bugs.openjdk.java.net/browse/JDK-8215412
>> Using a simple test program like this:
>> public class Test {
>>   public static void main (String ... args) {
>>     for (int i = 0; i < Integer.parseInt(args[0]); i++)
>>       System.out.println(args[1]);
>>   }
>> }
>> ... and stating the cost of running:
>> $ java Test 100000 tttttttttttttttttttttttttttttttttttttttttttttt | wc -l
>> ... I get a 15-30% reduction in cycles and wall clock time (larger
>> reduction the more output is produced).
>> Thanks!
>> /Claes

More information about the core-libs-dev mailing list