Java Reference
In-Depth Information
Although this performance issue is most easily understood when discussing file I/O, it is a
general issue that applies to almost every sort of I/O. The streams returned from a socket (via
the getInputStream() or getOutputStream() methods) operate in the same manner, and
performing I/O a byte at a time over a socket is quite slow. Here, too, always make sure that
the streams are appropriately wrapped with a buffering filter stream.
There are more subtle issues when using the ByteArrayInputStream and ByteArrayOut-
putStream classes. These classes are essentially just big in-memory buffers to begin with. In
many cases, wrapping them with a buffering filter stream means that data is copied twice:
once to the buffer in the filter stream, and once to the buffer in the ByteArrayInputStream
(or vice versa for output streams). Absent the involvement of any other streams, buffered I/O
should be avoided in that case.
When other filtering streams are involved, the question of whether or not to buffer becomes
more complicated. A common use case is to use these streams to serialize or deserialize data.
For example, Chapter 10 discusses various performance trade-offs involving explicitly man-
aging the data serialization of classes. A simple version of the writeObject() method in
that chapter looks like this:
private void
void writeObject ( ObjectOutputStream out ) throws
throws IOException {
iif ( prices == null
null ) {
makePrices ();
out . defaultWriteObject ();
protected void
throws IOException {
ByteArrayOutputStream baos = new
void makePrices () throws
new ByteArrayOutputStream ();
ObjectOutputStream oos = new
new ObjectOutputStream ( baos );
oos . writeObject ( prices );
oos . close ();
In this case, wrapping the baos stream in a BufferedOutputStream would suffer a perform-
ance penalty from copying the data one extra time.
In that example, it turned out to be much more efficient to compress the data in the prices
array, which resulted in this code:
Search WWH ::

Custom Search