trivial patch to reduce allocations in nio open* methods

Michael Skells mike.skells1 at gmail.com
Tue Mar 13 20:57:27 UTC 2018


Hi Alan,
This is using the default file system, on windows and unix

This was spotted with the development of the Scala compiler, but it would
be unaffected by this patch as described below

Some background -
The Scala compiler tends to write a lot more classes for a given source
file than Java, tens or even hundreds from a single source. I was working
or parallelising the code generation and optimisation of the back end of
the scala compiler and looking for object allocations that could be trimmed
amongst others things, mostly in the scala compiles and its runtime

We have some projects that will generate 100K class files for a compile,
and several hundred projects within the same codeball. When compiling
downstream projects within the IDEs we refer to classes from upstream
projects and there are lots of files read and parsed

We have hundreds of developers who are recompiling the codeball on a
regular basis, usually partially either in an IDE or CI environment, some
on Windows and some on Unix

The work was focussed primarily on providing business benefit in our
enterprise, but releasing what we could back to the open source compiler

Performance
This additional object creation is not a dominating, or even large impact
on the compiler performance, but all things add up to the end performance
and currently opening a file for write creates I think 5 objects ( the
HashMap, backing Object[], and 3 Map.Entry) and wastes a small amount of
CPU, and it seemed easy to fix for the common case :-). The production code
doesn't use this call path but we use CREATE_NEW explicitly as explained
later

The file opening & closing (particularly in windows, with an enterprise
software stack) is by far the dominant item, by orders of magnitude. We
can't currently write to Zip/Jar files because of the tool chain, and the
compiler is generating a stream of (FileName, byte[]), and there is no bulk
or stream file API that I am aware of

The benchmarking I did was on Java 8 (about 6 months ago), on 64 bit
windows 10 and 7, desktops from 4 to 12 cores, all 64 bit server JVM, with
local SSD

I did benchmark the use of different APIs (sync vs async NIO vs old file
IO) and how many writes concurrently to get the best throughput, on SSD
desktops, and the best seems to be sync NIO and over-committing the CPU
with 2 threads per hyperthreaded core (this seemed to reduce the OS CPU
overheads). Strangely async NIO didn't seem to benefit so much from this
over-commitment but I didn't dig into this. I did post to this group some
unexpected degradation with REFS filesystem "parallel IO anomaly with
windows REFS formatted drive" but as Bernt noted that filesystem was
removed from desktops

Incidentally, but slightly related the biggest unexpected performance boost
(on windows) was not using CREATE and TRUNCATE together but using
CREATE_NEW and coping with the unusual case of pre-existing files as an
exception (40% reduction in OS CPU!). I only found this by accidentally
deleting the profiling filter in JProbe for java.*, sun.* etc classes one
day :-) and profiling all the way to nio code. This code is around usage of
"truncateAfterOpen" in WindowsChannelFactory
This means that the default options cause 2 OS calls to open the file on
windows (one to create and the other to truncate), but I could not fix the
default case in a patch and I am not sure it is fixable :-(

I spotted this issue/optimisation in the Scala compiler development, but it
would be unaffected by this patch because we use specific flags, but I
thought that it would be useful to others.


Regards
Mike

On Tue, 13 Mar 2018 at 14:25 Alan Bateman <Alan.Bateman at oracle.com> wrote:

> On 13/03/2018 00:01, Michael Skells wrote:
>
> Hi,
>
> I am not sure what the status is for this patch
>
>
>
> Are you waiting for more input, or some update from me?
>
> Is this a viable patch?
>
> Is it just in the queue of minor noise to consider later?
>
> Do you have any data on how it helps the scala compiler? Also are you
> seeing this with the default file system or is something else (the zip file
> system maybe)? I ask as I would have expected the I/O cost and opening the
> file to dominant rather than processing the arguments that specify how the
> file is opened.
>
> BTW: I'm not opposed to changing anything here, instead I think we need a
> bit more of the story.
>
>
> -Alan
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/nio-dev/attachments/20180313/3b7f67b2/attachment.html>


More information about the nio-dev mailing list