I'm working with an ASCII input/output stream over a Socket and speed is critical. I've heard using the right Java technique really makes a difference. I have a textbook that says using Buffers is the best way, but also suggests chaining with DataInputStreamReader.
For output I'm using a BufferedOutputStream with OutputStreamWriter which seems to be fine. But I am unsure on what to use for the input stream. I'm working on new lines, so would Scanner be of any use? Speed is critical, I need to get the data off the network as fast as possible.
Thanks.
PH
Just for laughs...
With LOOPBACK, i.e. just running to localhost with local processes, on my machine, and with a suitably "stupid" client.
You'll note that this send 2M "1000 char" lines. It's simply a crude throughput test.
On my machine, loopback, I get ~190MB/sec transfer rate. Bytes, not bits. 190,000 lines/sec.
My point is that the "unsophisticated" way using bone stock Java sockets is quite fast. This will saturate any common network connection (meaning the network will be slowing you down more than your I/O here will).
Likely "fast enough".
What kind of traffic are you expecting?
If speed is absolutely critical, consider using NIO. Here's a code example posted for the exact same question.
http://lists.apple.com/archives/java-dev/2004/Apr/msg00051.html
EDIT: Here's another example
http://www.java2s.com/Code/Java/File-Input-Output/UseNIOtoreadatextfile.htm
EDIT 2: I wrote this microbenchmark to get you started on measuring the performance of various approaches. Some folks have commented that NIO will not perform faster because you will need to do more work to 'massage' the data into a usable form, so you can validate that based on whatever it is you're trying to do. When I ran this code on my machine, the NIO code was approximately 3 times faster with a 45 megabyte file, and 5 times faster with a 100 megabyte file.
A
Scanner
is used for delimited text. You didn't talk about what your data looks like so I can't comment on that.If you just want to read until each newline character, use
BufferedReader r = new BufferedReader(new InputStreamReader(Socket.getInputStream()))
and
r.readLine()
When you get a null value, you will know you have exhausted the data in the stream.
As far as speed is concerned, they are both just reading data out of the stream. So assuming you don't need the extra functionality of a
Scanner
, I don't see any particular reason to use one.I would do something with a BufferedReader along the lines of:
Depending on your situation you could have an additional thread that processes the items in 'lines' as its getting filled, but then you would need to use a different structure to back the collection- one that can be used concurrently.