twisted
twisted

Reputation: 21

When to use BufferedInput/OutputStreams in Java?

I have a client program that sends an encrypted object to a server, and am using a bunch of streams to do it:

    //httpOutput is the HTTPUrlConnection request stream
    Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    rsaCipher.init(Cipher.ENCRYPT_MODE, certificate);
    CipherOutputStream cipherOutput = new CipherOutputStream(httpOutput, rsaCipher);

    BufferedOutputStream bufferedOutput = new BufferedOutputStream(cipherOutput);
    ObjectOutputStream objectOutput = new ObjectOutputStream(bufferedOutput );

Am I putting the buffer in the right place/does it matter?

Upvotes: 2

Views: 987

Answers (3)

Stephen C
Stephen C

Reputation: 718718

Am I putting the buffer in the right place?

Yes. In general, it is best to put the buffered stream as close as possible to the code that produces or consumes the data. This is on the assumption that the lower layers can handle large chunks of data more efficiently than small chunks.

Does it matter?

It depends on what is underneath, and specifically on what the performance gain of chunking is at each level. If the performance gain is small, then it doesn't matter much. But if the performance gain is large (e.g. at the stage where you are doing system calls), then having the buffering in place very important.


There are a few situations where inserting a buffered stream could degrade performance (a bit). For example:

  • if the application code (the producer / consumer) is reading / writing data in large chunks, or
  • if the stream is writing to / reading from an in-memory buffer and there is no filtering / conversion in the stream stack that would benefit from chucking.

In these cases, the buffering does not help, and adds a small performance cost due to the extra method calls and per-call buffer state management. However, the performance penalty is unlikely to be significant, even if the streaming is a performance critical part of the application. (But if performance is an important requirement, profile it!)

Upvotes: 4

Thomas Owens
Thomas Owens

Reputation: 116159

You might be interested in reading the Java documentation on I/O Performance. Buffered streams allow you to deal with chunks of data instead of individuals bytes. In most cases, this allows for faster reading and writing from disk.

I've never done performance testing, but if I'm using a buffered stream, it's usually very early on in the wrapping. For example, I would buffer the httpOutput stream first, then apply the CipherOutputStream to that, then finally the ObjectOutputStream. However, I'm not sure why I do it that way, it's just the way I've always done it - apply the buffering as early as possible.

Upvotes: 2

MeBigFatGuy
MeBigFatGuy

Reputation: 28568

The Buffering should happen the closest to the raw stream as possible. in this case it should be wrapping the http output stream.

Upvotes: 2

Related Questions