Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Files.newInputStream creates slow InputStream

Tags:

java

On my Windows 7 Files.newInputStream returns sun.nio.ch.ChannelInputStream. When I tested its performance vs FileInputStream I was surprised to know that FileInputStream is faster.

This test

    InputStream in = new FileInputStream("test");
    long t0 = System.currentTimeMillis();
    byte[] a = new byte[16 * 1024];
    for (int n; (n = in.read(a)) != -1;) {
    }
    System.out.println(System.currentTimeMillis() - t0);

reads 100mb file in 125 ms. If I replace the first line with

InputStream in = Files.newInputStream(Paths.get("test"));

I get 320ms.

If Files.newInputStream is slower what advantages it has over FileInputStream?

like image 797
Evgeniy Dorofeev Avatar asked Nov 30 '13 06:11

Evgeniy Dorofeev


3 Answers

If you tested new FileInputStream second, you are probably just seeing the effect of cache priming by the operating system. It isn't plausible that Java is causing any significant difference to an I/O-bound process. Try it the other way around, and on a much larger dataset.

like image 184
user207421 Avatar answered Sep 28 '22 06:09

user207421


I don't want to be the buzzkill, but the javadoc doesn't state any advantages, nor does any documentation I could find

Opens a file, returning an input stream to read from the file. The stream will not be buffered, and is not required to support the mark or reset methods. The stream will be safe for access by multiple concurrent threads. Reading commences at the beginning of the file. Whether the returned stream is asynchronously closeable and/or interruptible is highly file system provider specific and therefore not specified.

I think the method is just a utility method not necessarily meant to replace or improve on FileInputStream. Note that the concurrency point might explain some slow down.

like image 26
Sotirios Delimanolis Avatar answered Sep 28 '22 08:09

Sotirios Delimanolis


Your FileInputStream and FileOutputstreams might introduce long GC pauses

Every time you create either a FileInputStream or a FileOutputStream, you are creating an object. Even if you close it correctly and promptly, it will be put into a special category that only gets cleaned up when the garbage collector does a full GC. Sadly, due to backwards compatibility constraints, this is not something that can be fixed in the JDK anytime soon as there could be some code out there where somebody has extended FileInputStream / FileOutputStream and is relying on those finalize() methods to ensure the call to close().

The solution (at least if you are using Java 7 or newer) is not too hard — just switch to Files.newInputStream(...) and Files.newOutputStream(...)

https://dzone.com/articles/fileinputstream-fileoutputstream-considered-harmful

like image 40
duvanjamid Avatar answered Sep 28 '22 06:09

duvanjamid