From: arun.darra on 28 Mar 2010 12:15 Hi, Could someone pls tell me why is the NIO buffering faster than the IO BufferedReader class. I agree NIO uses FileChannels to access the file. But it in turn uses the FileInputStream. Example 1: BufferedReader BufferedReader reader = new BufferedReader(new FileInputStream("File.txt")); reader.read(....); Example 2: NIO Bufferes FileChannel fc = new FileInputStream("File.txt").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); fc.read(buffer); Keeping the fact in mind, in both cases the data is being buffered - then how is the NIO method faster than IO Buffer.
From: Peter Duniho on 28 Mar 2010 12:28 arun.darra(a)gmail.com wrote: > Hi, > > Could someone pls tell me why is the NIO buffering faster than the IO > BufferedReader class. [...] Is it? If you have a concise-but-complete code example that demonstrates that one is reliably faster than the other, you should include that here as part of your question. That way, it be ensured that everyone is talking about the same implementation, and the same factors that might account for a difference (including the possibility of implementation errors in which one i/o technique winds up favored over the other). If you don't have a concise-but-complete code example that demonstrates that one is reliably faster than the other, then it seems to me you've put the cart before the horse. Pete
From: Arne Vajhøj on 28 Mar 2010 18:07 On 28-03-2010 12:15, arun.darra(a)gmail.com wrote: > Could someone pls tell me why is the NIO buffering faster than the IO > BufferedReader class. > > I agree NIO uses FileChannels to access the file. But it in turn uses > the FileInputStream. > > Example 1: BufferedReader > > BufferedReader reader = new BufferedReader(new > FileInputStream("File.txt")); > reader.read(....); > > Example 2: NIO Bufferes > > FileChannel fc = new FileInputStream("File.txt").getChannel(); > ByteBuffer buffer = ByteBuffer.allocate(1024); > fc.read(buffer); > > Keeping the fact in mind, in both cases the data is being buffered - > then how is the NIO method faster than IO Buffer. My expectation would be that: - the difference is very small - NIO may be slightly faster because it was designed later and performance could have been a design criteria possibly resulting in a faster implementation Actual difference will depend on Java vendor, Java version, OS, CPU, IO system etc.. For SUN Java 1.6, WinXP and my PC: Unbuffered small reads : 26844 Unbuffered large reads : 687 Buffered small reads : 1406 Buffered large reads : 688 Nio map small reads : 3656 Nio map large reads : 563 Nio read small reads : 3547 Nio read large reads : 531 Random access small reads : 26359 Random access large reads : 656 Unbuffered small reads : 26875 Unbuffered large reads : 500 Buffered small reads : 938 Buffered large reads : 469 Nio map small reads : 3453 Nio map large reads : 328 Nio read small reads : 3437 Nio read large reads : 375 Random access small reads : 26125 Random access large reads : 469 Unbuffered small reads : 26313 Unbuffered large reads : 453 Buffered small reads : 937 Buffered large reads : 485 Nio map small reads : 3406 Nio map large reads : 328 Nio read small reads : 3469 Nio read large reads : 437 Random access small reads : 26719 Random access large reads : 734 (see code below) Arne ======================= import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.RandomAccessFile; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class ReadTest { static final int TOT = 100000000; static final int SMALL = 10; static final int LARGE = 1000000; static final String FILE_NAME = "C:/readtest.dat"; private static final int REP = 3; public static void main(String[] args) throws Exception { createFile(); for(int i = 0; i < REP; i++) { (new UnbufferedSmallReadTest()).doTest(); (new UnbufferedLargeReadTest()).doTest(); (new BufferedSmallReadTest()).doTest(); (new BufferedLargeReadTest()).doTest(); (new NioMapSmallReadTest()).doTest(); (new NioMapLargeReadTest()).doTest(); (new NioReadSmallReadTest()).doTest(); (new NioReadLargeReadTest()).doTest(); (new RandomAccessSmallReadTest()).doTest(); (new RandomAccessLargeReadTest()).doTest(); } } private static void createFile() throws IOException { OutputStream f = new FileOutputStream(FILE_NAME); for(int i = 0; i < TOT; i++) { f.write((i % 256)); } } } abstract class GenericReadTest { public void doTest() throws Exception { long t1 = System.currentTimeMillis(); readAndCheck(); long t2 = System.currentTimeMillis(); System.out.println(getType() + " : " + (t2 - t1)); } protected abstract void readAndCheck() throws Exception; protected abstract int getReadSize(); public abstract String getType(); } abstract class UnbufferedReadTest extends GenericReadTest { protected void readAndCheck() throws IOException { InputStream f = new FileInputStream(ReadTest.FILE_NAME); byte[] b = new byte[getReadSize()]; int n; int ix = 0; while((n = f.read(b)) >= 0) { for(int i = 0; i < n; i++) { if(b[i] != (byte)(ix % 256)) { throw new IOException("Bad data read - offset " + ix + " expected " + (byte)(ix % 256) + " found " + b[i]); } ix++; } } } } abstract class BufferedReadTest extends GenericReadTest { protected void readAndCheck() throws IOException { BufferedInputStream f = new BufferedInputStream(new FileInputStream(ReadTest.FILE_NAME)); byte[] b = new byte[getReadSize()]; int n; int ix = 0; while((n = f.read(b)) >= 0) { for(int i = 0; i < n; i++) { if(b[i] != (byte)(ix % 256)) { throw new IOException("Bad data read - offset " + ix + " expected " + (byte)(ix % 256) + " found " + b[i]); } ix++; } } } } abstract class NioMapReadTest extends GenericReadTest { protected void readAndCheck() throws IOException { FileChannel f2 = (new FileInputStream(ReadTest.FILE_NAME)).getChannel(); ByteBuffer f = f2.map(FileChannel.MapMode.READ_ONLY, 0, ReadTest.TOT); byte[] b = new byte[getReadSize()]; int ix = 0; while(ix < ReadTest.TOT) { f.get(b); for(int i = 0; i < b.length; i++) { if(b[i] != (byte)(ix % 256)) { throw new IOException("Bad data read - offset " + ix + " expected " + (byte)(ix % 256) + " found " + b[i]); } ix++; } } } } abstract class NioReadReadTest extends GenericReadTest { protected void readAndCheck() throws IOException { FileChannel f = (new FileInputStream(ReadTest.FILE_NAME)).getChannel(); ByteBuffer b2 = ByteBuffer.allocate(getReadSize()); byte[] b = new byte[getReadSize()]; int n; int ix = 0; while((n = f.read(b2)) >= 0) { b2.get(b); for(int i = 0; i < n; i++) { if(b[i] != (byte)(ix % 256)) { throw new IOException("Bad data read - offset " + ix + " expected " + (byte)(ix % 256) + " found " + b[i]); } ix++; } } } } abstract class RandomAccessReadTest extends GenericReadTest { protected void readAndCheck() throws IOException { RandomAccessFile f = new RandomAccessFile(ReadTest.FILE_NAME, "r"); byte[] b = new byte[getReadSize()]; int n; int ix = 0; while((n = f.read(b)) >= 0) { for(int i = 0; i < n; i++) { if(b[i] != (byte)(ix % 256)) { throw new IOException("Bad data read - offset " + ix + " expected " + (byte)(ix % 256) + " found " + b[i]); } ix++; } } } } class UnbufferedSmallReadTest extends UnbufferedReadTest { protected int getReadSize() { return ReadTest.SMALL; } public String getType() { return "Unbuffered small reads"; } } class UnbufferedLargeReadTest extends UnbufferedReadTest { protected int getReadSize() { return ReadTest.LARGE; } public String getType() { return "Unbuffered large reads"; } } class BufferedSmallReadTest extends BufferedReadTest { protected int getReadSize() { return ReadTest.SMALL; } public String getType() { return "Buffered small reads"; } } class BufferedLargeReadTest extends BufferedReadTest { protected int getReadSize() { return ReadTest.LARGE; } public String getType() { return "Buffered large reads"; } } class NioMapSmallReadTest extends NioMapReadTest { protected int getReadSize() { return ReadTest.SMALL; } public String getType() { return "Nio map small reads"; } } class NioMapLargeReadTest extends NioMapReadTest { protected int getReadSize() { return ReadTest.LARGE; } public String getType() { return "Nio map large reads"; } } class NioReadSmallReadTest extends NioMapReadTest { protected int getReadSize() { return ReadTest.SMALL; } public String getType() { return "Nio read small reads"; } } class NioReadLargeReadTest extends NioMapReadTest { protected int getReadSize() { return ReadTest.LARGE; } public String getType() { return "Nio read large reads"; } } class RandomAccessSmallReadTest extends RandomAccessReadTest { protected int getReadSize() { return ReadTest.SMALL; } public String getType() { return "Random access small reads"; } } class RandomAccessLargeReadTest extends RandomAccessReadTest { protected int getReadSize() { return ReadTest.LARGE; } public String getType() { return "Random access large reads"; } }
From: Mike Amling on 28 Mar 2010 18:57 arun.darra(a)gmail.com wrote: > Hi, > > Could someone pls tell me why is the NIO buffering faster than the IO > BufferedReader class. > > I agree NIO uses FileChannels to access the file. But it in turn uses > the FileInputStream. > > Example 1: BufferedReader > > BufferedReader reader = new BufferedReader(new > FileInputStream("File.txt")); > reader.read(....); How do you get new BufferedReader(new FileInputStream(...)) to compile? All the BufferedReader constructors require a Reader argument. > > Example 2: NIO Bufferes > > FileChannel fc = new FileInputStream("File.txt").getChannel(); > ByteBuffer buffer = ByteBuffer.allocate(1024); > fc.read(buffer); > > Keeping the fact in mind, in both cases the data is being buffered - > then how is the NIO method faster than IO Buffer. Any Reader would have to attempt to parse an incoming byte sequence into 16-bit chars according to an encoding. Your NIO example is not doing any such parsing of the data. --Mike Amling
From: EJP on 29 Mar 2010 02:50
On 29/03/2010 3:15 AM, arun.darra(a)gmail.com wrote: > > Could someone pls tell me why is the NIO buffering faster than the IO > BufferedReader class. Is it? > I agree NIO uses FileChannels to access the file. And ByteBuffers. > But it in turn uses the FileInputStream. No it doesn't. > BufferedReader reader = new BufferedReader(new > FileInputStream("File.txt")); Doesn't compile. Even if you fix that, you are introducing byte-to-char overheads here that you don't have in your NIO test. So you are comparing apples and oranges. > Keeping the fact in mind, in both cases the data is being buffered - > then how is the NIO method faster than IO Buffer. I doubt that it is any faster at all, unless you use direct buffers, of a much larger size. |