title: Java I/O vs NIO: Quick Benchmark Comparison
body: <p>I recently read that in newer computers Java's I/O performs better than NIO because of the new availability of multi-core machines.</p>
  
  <p>I ran a quick test comparing the transfer time of I/O and NIO over the LAN using the localhost loopback address.</p>
  
  <p>Note: This is using JDK 7</p>
  
  <p>The results (3 trials):</p>
  
  <p>I/O transfers averaged <strong>21789.3ms</strong></p>
  
  <p>NIO transfers averaged <strong>22771.0ms</strong></p>
  
  <p>It is also worth noting that CPU usage appeared to be around 10% higher on each NIO transfer as compared to the I/O.</p>
  
  <p>My question for you is if my comparison code is fair?  Did I write good/equal I/O and NIO code?  If not, how can I improve and re-run this test?</p>
  
  <pre><code>    public static void main(String[] args) {
      System.out.println("Initiating test sequence...");
      new Thread(new Client()).start();
      try {
          System.out.println("Server I/O initiating...");
          ServerSocket server = new ServerSocket(5555);
          Socket sock = server.accept();
          System.out.println("Server connected to client successfully");
          InputStream is = sock.getInputStream();
          File output = new File("C:/test_root/video.avi");
          FileOutputStream fos = new FileOutputStream(output);
          byte[] data = new byte[1024];
          int len=0;
          System.out.println("Server initiating transfer - Timer starting");
          long start = System.currentTimeMillis();
          while((len=is.read(data))&gt;0) {
              fos.write(data, 0, len);
              fos.flush();
          }
          fos.close();
          is.close();
          sock.close();
          server.close();
          long end = System.currentTimeMillis();
          System.out.println("Network I/O transfer time = "+(end-start)+"ms");
  
          System.out.println("Server NIO initiating...");
          ServerSocketChannel serverChan = ServerSocketChannel.open();
          serverChan.bind(new InetSocketAddress(5555));
          SocketChannel chan = serverChan.accept();
          chan.configureBlocking(false);
          System.out.println("Server channel connected");
          FileChannel fc = (FileChannel) Files.newByteChannel(Paths.get("C:/test_root/video.avi"), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
          ByteBuffer buff = ByteBuffer.allocate(1024);
          System.out.println("Server initiating transfer - Timer starting");
          start = System.currentTimeMillis();
          while(chan.read(buff)&gt;=0 || buff.position() &gt; 0) {
              buff.flip();
              fc.write(buff);
              buff.compact();
          }
          chan.close();
          fc.close();
          serverChan.close();
          end = System.currentTimeMillis();
          System.out.println("Network NIO transfer time = "+(end-start)+"ms");
      } catch (IOException e) {
          e.printStackTrace();
      }
      System.out.println("Test completed!");
  }
  
  static class Client implements Runnable {
  
      public void run() {
          try {
              System.out.println("Client I/O initiating...");
              Socket sock = new Socket("localhost", 5555);
              System.out.println("Client connected to server successfully!");
              OutputStream os = sock.getOutputStream();
              File input = new File(System.getProperty("user.home")+"/Documents/clip0025.avi");
              FileInputStream fis = new FileInputStream(input);
              byte[] data = new byte[1024];
              int len=0;
              int tot=0;
              int perc=0;
              while((len=fis.read(data))&gt;0) {
                  os.write(data, 0, len);
                  os.flush();
                  tot+=len;
                  int prev = perc;
                  perc = getPercentage(tot, input.length());
                  if(perc !=prev &amp;&amp; (perc == 10 || perc == 25 || perc == 50 || perc == 75 || perc == 98))
                      System.out.println("Client reporting: "+perc+"% read");
              }
              os.close();
              fis.close();
              sock.close();
  
              try {
                  Thread.sleep(2000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println("Client NIO initiating...");
              SocketChannel sc = SocketChannel.open();
              boolean connected = sc.connect(new InetSocketAddress("localhost",5555));
              if(!connected)
                  connected = sc.finishConnect();
              if(!connected)
                  throw(new IOException("Client failed to connect"));
              System.out.println("Client channel connected");
              sc.configureBlocking(false);
              FileChannel fc = (FileChannel) Files.newByteChannel(input.toPath(), StandardOpenOption.READ);
              ByteBuffer buff = ByteBuffer.allocate(1024);
              len=0;
              tot=0;
              while((len=fc.read(buff))&gt;=0||buff.position()&gt;0) {
                  buff.flip();
                  sc.write(buff);
                  buff.compact();
                  tot+=len;
                  int prev = perc;
                  perc = getPercentage(tot, input.length());
                  if(perc !=prev &amp;&amp; (perc == 10 || perc == 25 || perc == 50 || perc == 75 || perc == 98))
                      System.out.println("Client reporting: "+perc+"% read");
              }
              sc.close();
              fc.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>Additional Info:</p>
  
  <p>Windows Vista (SP2) on Dell Studio XPS 435MT</p>
  
  <p>1st gen i7 quad-core processor 2.67GHz</p>
  
  <p>6GB RAM</p>
  
  <p>64-bit architecture</p>