Java IO compared to NIO

J

John B. Matthews

This presentation compares Java synchronous (java.io.*) to asynchronous
(java.nio.*) I/O in a high volume SMTP application, finding a measurable
benefit for the former with modern threading libraries and multi-core
machines.

<http://www.mailinator.com/tymaPaulMultithreaded.pdf>

Some discussion may be found here:

<http://developers.slashdot.org/story/10/07/27/1925209>

The few times the choice has come up, we implemented synchronous I/O,
profiled it, found it met the requirements and declared victory. Lacking
much experience in this area, I'd welcome critical comments.
 
A

Arved Sandstrom

John said:
This presentation compares Java synchronous (java.io.*) to asynchronous
(java.nio.*) I/O in a high volume SMTP application, finding a measurable
benefit for the former with modern threading libraries and multi-core
machines.

<http://www.mailinator.com/tymaPaulMultithreaded.pdf>

Some discussion may be found here:

<http://developers.slashdot.org/story/10/07/27/1925209>

The few times the choice has come up, we implemented synchronous I/O,
profiled it, found it met the requirements and declared victory. Lacking
much experience in this area, I'd welcome critical comments.
Yeah, I was just reading about this Paul Tyma discovery myself. I'm not
prepared to comment on it other than to say that the presented arguments
are plausible. I'll also note that the main argument has been made
before - it's not a stunning new revelation.

On a related note, if "old" I/O meets your requirements then what more
do you need? :) I've been generally content with "old" I/O in most
situations.

And as an aside, one thing I noticed with NIO when it came out,
specifically concerning use of the Selector, was that the new API
promoted a fair bit of black-box copy-paste programming. Admittedly I
have only a small set of observations, but quite frankly the only time I
ran across a group of people that thoroughly understood their NIO code
was when their original code had been C code and they were using the
select() call there. It might perhaps be more accurate to say that NIO
did not *promote* this copy-paste programming; it simply perpetuated it
- it wasn't easier for the average programmer to understand than "old" I/O.

AHS
 
D

Daniel Pitts

Yeah, I was just reading about this Paul Tyma discovery myself. I'm not
prepared to comment on it other than to say that the presented arguments
are plausible. I'll also note that the main argument has been made
before - it's not a stunning new revelation.

On a related note, if "old" I/O meets your requirements then what more
do you need? :) I've been generally content with "old" I/O in most
situations.

And as an aside, one thing I noticed with NIO when it came out,
specifically concerning use of the Selector, was that the new API
promoted a fair bit of black-box copy-paste programming. Admittedly I
have only a small set of observations, but quite frankly the only time I
ran across a group of people that thoroughly understood their NIO code
was when their original code had been C code and they were using the
select() call there. It might perhaps be more accurate to say that NIO
did not *promote* this copy-paste programming; it simply perpetuated it
- it wasn't easier for the average programmer to understand than "old" I/O.
It was never meant to be easier, it was meant to reduce the number of
threads required for handling multiple "streams" of data. It is actually
far more complicated to get correct, often requiring a state machine.
For a single stream, I suspect there is no speed benefit.

As far as efficiency goes, my guess is that there is a sweet-spot for
the number of streams-per-thread which outperforms regular IO. This
sweet-spot would depend on many factors, including overall system-load,
threading implementation, low-level select implementation, and stream
throughput.

Just a thought.
 
J

John B. Matthews

It was never meant to be easier, it was meant to reduce the number of
threads required for handling multiple "streams" of data. It is
actually far more complicated to get correct, often requiring a state
machine. For a single stream, I suspect there is no speed benefit.

As far as efficiency goes, my guess is that there is a sweet-spot for
the number of streams-per-thread which outperforms regular IO. This
sweet-spot would depend on many factors, including overall
system-load, threading implementation, low-level select
implementation, and stream throughput.

Thanks, both, for commenting on this. I also found this thread helpful:

<http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/dd8005f33b883d02>
 
A

Arved Sandstrom

Daniel said:
It was never meant to be easier, it was meant to reduce the number of
threads required for handling multiple "streams" of data. It is actually
far more complicated to get correct, often requiring a state machine.
[ SNIP ]

Your observations are true. If I were to make my point another way, it
would be that it's human nature to equate "more capable" with "easier to
use". When Java NIO appeared in 1.4 it wasn't advertised as being
easier, but it was certainly advertised - frequently - as "fixing" Java
I/O. No small number of Java programmers, the majority of them
relatively inexperienced (and I mean inexperienced both in the language
and in matters I/O), took "fixed" to mean "prefer NIO to 'old'
I/O"...which wasn't necessarily the right choice. Because, as you point
out, it's often more complicated to get NIO right.

AHS
 
J

John B. Matthews

Esmond Pitt said:
You should also have a look at 'Taming the NIO Circus' at forums.sun.com:
http://forums.sun.com/thread.jspa?threadID=459338&start=0

Thank you for this link; the code is exemplary: both commendable and
cautionary. It highlights Daniel Pitts' point that NIO tends to be more
complex. Mindful of AHS's observation that the inexperienced tend to
prefer NIO without good reason, I am always looking for heuristics that
might inform the right choice.
 
A

Arved Sandstrom

John said:
Thank you for this link; the code is exemplary: both commendable and
cautionary. It highlights Daniel Pitts' point that NIO tends to be more
complex. Mindful of AHS's observation that the inexperienced tend to
prefer NIO without good reason, I am always looking for heuristics that
might inform the right choice.
NIO is a large API, as you know. If we are talking specifically about
using Selectors and Channels in a Java project, and YMMV here, I've
found it to be a useful exercise to work (or have worked) a problem in C
using select (or poll/epoll, depends on what you've got available).

I'm not going to make this a hard recommendation, but speaking only for
myself I've found that my comfort level with Java I/O, both "old" and
"new", has been enhanced by tackling all of the equivalent situations in
C (usually) over the decades. By doing so one tends to have a better
understanding, for I/O specifically, of what Java is doing under the
hood on your system.

AHS
 
E

Esmond Pitt

The Sun (Oracle) JRE uses NIO to implement java.io.

It uses *some of* NIO to implement java.io. It doesn't use for example
ByteBuffers, or it didn't last time I looked. It would be more accurate
to say that they both use a thin layer over the Sockets API.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top