Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > network effeciently

Reply
Thread Tools

network effeciently

 
 
Andy Fish
Guest
Posts: n/a
 
      05-11-2004
<snipped everything>
It seems very unlikely that the problem is happening inside java - with
throughputs as low as the OP is getting, you would have time to put each
character in a DOM tree then process it with XSL before you started hitting
CPU performance problems.

The best way to investigate is to watch the CPU usage and monitor the total
number of bytes on the network interface. if neither of these is maxing out
I would suspect you have a serious synchronization problem (or sleep
statement in your program

Andy


 
Reply With Quote
 
 
 
 
Parker Thompson
Guest
Posts: n/a
 
      05-11-2004
In our last episode Chris Uppal exclaimed:

:> Don't write your data one byte at a time. You are wasting a lot of time
:> looping (and probably sending 1-byte packets with 32-48 bytes of
:> overhead - I'm not sure of the size of a TCP header offhand).
:
:This would be sensible and intelligent advice -- except that you haven't
:noticed that he's wrapping the raw networking streams in
:Buffered{Out/In}putStreams.

A question on this point: does the buffer size have an impact? I'm
unclear how the in/out stream buffers affect the size of the tcp packets.
Should I be setting a non-default buffer size, or perhaps just skip
buffering alltogether so I know what's going on?

Thanks,

pt.
 
Reply With Quote
 
 
 
 
Knute Johnson
Guest
Posts: n/a
 
      05-12-2004
Roedy Green wrote:

> On Tue, 11 May 2004 09:22:29 +0100, Yu Song <(E-Mail Removed)> wrote or
> quoted :
>
>
>>It could be 100 times faster(depends on your connection) if you
>>read/write a chunk of data.

>
>
> There are two levels of overhead, talking to the socket, and talking
> to the buffered reader. Each kind of call has overhead. The bigger
> your buffer, the fewer calls to the underlying socket layer.
>
> If you are reading a giant chunk of raw bytes, DON'T use a
> BufferedInputStream. Use an unbuffered InputStream, and do it all in
> one giant I/O for maximum efficiency.
>
> see http://mindprod.com/jgloss/buffer.html for other hints on
> buffering.


Roedy:

I didn't think that unbuffered would be as good as buffered so I wrote a
couple of test programs and found that reading a whole array at a time
was faster than single bytes but that buffering single byte reads was
almost as good as buffered or multibyte. The difference between
buffered and unbuffered multibyte reads was small but unbuffered was
definitely faster.

Here are my test programs.

import java.io.*;
import java.net.*;
import java.util.*;

public class TestServer {
public static void main(String[] args) {
byte[] b = new byte[1000];
Random r = new Random();
while (true) {
try {
ServerSocket ss = new ServerSocket(8192);
System.out.println("Waiting for a connection");
Socket s = ss.accept();
System.out.println("Connected to: " +
s.getInetAddress().getHostAddress());
ss.close();
OutputStream os = s.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
for (int i=0; i<5000; i++) {
r.nextBytes(b);
bos.write(b,0,b.length);
}
os.close();
s.close();
} catch (IOException ioe) {
System.out.println(ioe);
}
System.out.println("Done\n");
}
}
}

import java.io.*;
import java.net.*;

public class TestClient {
public static void main(String[] args) {
try {
byte[] buf = new byte[1000];
int b;
long start,stop;

String host = (String)args[0];
int port = Integer.parseInt(args[1]);
Socket s = new Socket(host,port);
System.out.println("Connected");
InputStream is = s.getInputStream();
start = System.currentTimeMillis();
while ((b = is.read()) != -1) ;
stop = System.currentTimeMillis();
System.out.println("Unbuffered, one byte at a time: " +
(stop - start) / 1000.0);
is.close();
s.close();
System.out.println("Done\n");

s = new Socket(host,port);
System.out.println("Connected");
is = s.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
start = System.currentTimeMillis();
while ((b = bis.read()) != -1) ;
stop = System.currentTimeMillis();
System.out.println("Buffered, one byte at a time: " +
(stop - start) / 1000.0);
bis.close();
s.close();
System.out.println("Done\n");

s = new Socket(host,port);
System.out.println("Connected");
is = s.getInputStream();
bis = new BufferedInputStream(is);
start = System.currentTimeMillis();
while ((b = bis.read(buf)) != -1) ;
stop = System.currentTimeMillis();
System.out.println("Buffered, 1000 bytes at a time: " +
(stop - start) / 1000.0);
bis.close();
s.close();
System.out.println("Done\n");

s = new Socket(host,port);
System.out.println("Connected");
is = s.getInputStream();
start = System.currentTimeMillis();
while ((b = is.read(buf)) != -1) ;
stop = System.currentTimeMillis();
System.out.println("UnBuffered, 1000 bytes at a time: " +
(stop - start) / 1000.0);
is.close();
s.close();
System.out.println("Done\n");
} catch (Exception e) {
System.out.println(e);
}
}
}



--

Knute Johnson
email s/nospam/knute/
Molon labe...
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      05-12-2004
On Wed, 12 May 2004 01:10:50 GMT, Knute Johnson
<(E-Mail Removed)> wrote or quoted :

>I didn't think that unbuffered would be as good as buffered so I wrote a
>couple of test programs and found that reading a whole array at a time
>was faster than single bytes but that buffering single byte reads was
>almost as good as buffered or multibyte. The difference between
>buffered and unbuffered multibyte reads was small but unbuffered was
>definitely faster.


That sort of test you must run over and over and average the results.

I'm surprised at your result. How many times did you run the test?

--
Canadian Mind Products, Roedy Green.
Coaching, problem solving, economical contract programming.
See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
 
Reply With Quote
 
Knute Johnson
Guest
Posts: n/a
 
      05-12-2004
Roedy Green wrote:
> On Wed, 12 May 2004 01:10:50 GMT, Knute Johnson
> <(E-Mail Removed)> wrote or quoted :
>
>
>>I didn't think that unbuffered would be as good as buffered so I wrote a
>>couple of test programs and found that reading a whole array at a time
>>was faster than single bytes but that buffering single byte reads was
>>almost as good as buffered or multibyte. The difference between
>>buffered and unbuffered multibyte reads was small but unbuffered was
>>definitely faster.

>
>
> That sort of test you must run over and over and average the results.
>
> I'm surprised at your result. How many times did you run the test?
>


I tried it a few times. It sends 5 megabytes of random bytes. I'll try
it with 500mb and see how that turns out.

--

Knute Johnson
email s/nospam/knute/
Molon labe...
 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      05-12-2004
Parker Thompson wrote:

> > This would be sensible and intelligent advice -- except that you haven't
> > noticed that he's wrapping the raw networking streams in
> > Buffered{Out/In}putStreams.

>
> A question on this point: does the buffer size have an impact?


Whatever effect it may have, it's unlikely to explain what you are seeing.

I haven't checked the code, but I thing it would be quite difficult to persuade
a BufferedOuputStream to send very small IP packets, at least if you are in a
tight loop trying to write to the network. For instance, if you created the
stream with a 1-byte buffer -- surely the worst possible case -- then went into
a loop trying to send data through it, then
- Each byte would be sent to the underlying
Java network code individually.
- The underlying code would /probably/ have no
internal buffering and so would send each byte
directly to the OS.
- The OS would buffer up the data using "Nagle's
algorithm" and so end up putting it on the wire in
full sized IP packets anyway.

("Nagle's algorithm", is the process where the OS doesn't send data out
immediately if that data would not fill an IP packet, but instead waits for a
short time (a few millisecs I think) to see if the application will add any
more data. It's controlled by one of the socket options, but is turned on by
default).

That would have considerable overhead from all the extra system calls, which
would definitely slow things down, but not to the extent where it was taking
around 100 microseconds to go round each iteration of your loop.


> I'm
> unclear how the in/out stream buffers affect the size of the tcp packets.


Unless you disable Nagle's algorithm, it's very difficult to control the size
of the packets. Unless you have an application that needs to control /when/
the data is sent with a granularity of less than a few millisecs (which is rare
but not unheard of -- I needed it once) then Nagle is your friend.


> Should I be setting a non-default buffer size, or perhaps just skip
> buffering alltogether so I know what's going on?


These are both options that you may want to consider *after* you've found and
fixed whatever is causing the problems you are seeing. The way you have the
code now (judging by the extracts you posted) is fine as is. It is clear and
simple and should be reasonably efficient. As with all optimisation, you do it
*after* the code is working and in response to an /actual, measurable/
performance problem. You don't go writing complicated code just for the hell
of it (though it would seem that some of the other posters in this thread don't
agree The measurements I posted earlier indicate that it highly unlikely
that the use of single-byte writes into a buffered stream can cause the kind of
problems you are seeing (remember *four orders of magnitude* !), so I think you
have to look elsewhere. The advice Andy Fish posted about checking to see
what's maxed-out is good.

Still, if you want to see what's going on the network then get yourself a copy
of ethereal (free at <www.ethereal.com>). It may help you focuss on the real
problem. If it turns out that you /are/ sending tiny packets then it's
probably a bug in your code for setting up the buffering. If not then you will
be able to look elsewhere without distracting yourself with packet sizes.

-- chris






 
Reply With Quote
 
Yu Song
Guest
Posts: n/a
 
      05-12-2004
Knute Johnson wrote:
> Roedy Green wrote:
>
>> On Tue, 11 May 2004 09:22:29 +0100, Yu Song <(E-Mail Removed)> wrote or
>> quoted :
>>
>>
>>> It could be 100 times faster(depends on your connection) if you
>>> read/write a chunk of data.

>>
>>
>>
>> There are two levels of overhead, talking to the socket, and talking
>> to the buffered reader. Each kind of call has overhead. The bigger
>> your buffer, the fewer calls to the underlying socket layer.
>> If you are reading a giant chunk of raw bytes, DON'T use a
>> BufferedInputStream. Use an unbuffered InputStream, and do it all in
>> one giant I/O for maximum efficiency.
>>
>> see http://mindprod.com/jgloss/buffer.html for other hints on
>> buffering.

>
>
> Roedy:
>
> I didn't think that unbuffered would be as good as buffered so I wrote a
> couple of test programs and found that reading a whole array at a time
> was faster than single bytes but that buffering single byte reads was
> almost as good as buffered or multibyte. The difference between
> buffered and unbuffered multibyte reads was small but unbuffered was
> definitely faster.
>
> Here are my test programs.
>
> import java.io.*;
> import java.net.*;
> import java.util.*;
>
> public class TestServer {
> public static void main(String[] args) {
> byte[] b = new byte[1000];
> Random r = new Random();
> while (true) {
> try {
> ServerSocket ss = new ServerSocket(8192);
> System.out.println("Waiting for a connection");
> Socket s = ss.accept();
> System.out.println("Connected to: " +
> s.getInetAddress().getHostAddress());
> ss.close();
> OutputStream os = s.getOutputStream();
> BufferedOutputStream bos = new BufferedOutputStream(os);
> for (int i=0; i<5000; i++) {
> r.nextBytes(b);
> bos.write(b,0,b.length);
> }
> os.close();
> s.close();
> } catch (IOException ioe) {
> System.out.println(ioe);
> }
> System.out.println("Done\n");
> }
> }
> }
>



Because you know the exact data size you will receive.

Try this client code below (similar to yours but the size of buffer is 512)

//TestClient.java
import java.io.*;
import java.net.*;

public class TestClient {
public static void main(String[] args) {
try {
byte[] buf = new byte[512];
int b;
long start,stop;
String host = (String)args[0];
int port = Integer.parseInt(args[1]);
Socket s = new Socket(host,port);
InputStream is = s.getInputStream();
System.out.println("Connected");
BufferedInputStream bis = new BufferedInputStream(is);
start = System.currentTimeMillis();
while ((b = bis.read(buf)) != -1) ;
stop = System.currentTimeMillis();
System.out.println("Buffered, 512 bytes at a time: " +
(stop - start) / 1000.0);
bis.close();
s.close();
System.out.println("Done\n");

s = new Socket(host,port);
System.out.println("Connected");
is = s.getInputStream();
start = System.currentTimeMillis();
while ((b = is.read(buf)) != -1) ;
stop = System.currentTimeMillis();
System.out.println("UnBuffered, 512 bytes at a time: " +
(stop - start) / 1000.0);
is.close();
s.close();
System.out.println("Done\n");
} catch (Exception e) {
System.out.println(e);
}
}
}


--
Song

More info.:
http://www.dcs.warwick.ac.uk/~esubbn/

 
Reply With Quote
 
Nigel Wade
Guest
Posts: n/a
 
      05-12-2004
Parker Thompson wrote:
> Hello,
>
> I am trying to send files over the network using tcp sockets and am
> getting horrible speeds even over fast connections, perhaps 10k/sec where
> I would expect at least a factor of 10 greater. I feel like this should
> be pretty simple, but can't seem to figure it out.
>


What's your network bandwidth, and what bandwidht are you actually seeing?

Also, what else is using the network? You might be competing with Sasser

--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : http://www.velocityreviews.com/forums/(E-Mail Removed)
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
 
Reply With Quote
 
Knute Johnson
Guest
Posts: n/a
 
      05-12-2004
Roedy Green wrote:
> On Wed, 12 May 2004 01:10:50 GMT, Knute Johnson
> <(E-Mail Removed)> wrote or quoted :
>
>
>>I didn't think that unbuffered would be as good as buffered so I wrote a
>>couple of test programs and found that reading a whole array at a time
>>was faster than single bytes but that buffering single byte reads was
>>almost as good as buffered or multibyte. The difference between
>>buffered and unbuffered multibyte reads was small but unbuffered was
>>definitely faster.

>
>
> That sort of test you must run over and over and average the results.
>
> I'm surprised at your result. How many times did you run the test?
>


Roedy:

Here are the results in seconds for 500,000,000 bytes on my local
100mbit network. I think bigger arrays are probably slightly faster too.

C:\JavaProjects\widgets>java TestClient 192.168.3.3 8192
Connected
Unbuffered, one byte at a time: 1769.469
Done

Connected
Buffered, one byte at a time: 43.078
Done

Connected
Buffered, 1000 bytes at a time: 42.563
Done

Connected
UnBuffered, 1000 bytes at a time: 42.719
Done


C:\JavaProjects\widgets>

--

Knute Johnson
email s/nospam/knute/
Molon labe...
 
Reply With Quote
 
Knute Johnson
Guest
Posts: n/a
 
      05-12-2004
Yu Song wrote:
> Knute Johnson wrote:
>
>> Roedy Green wrote:
>>
>>> On Tue, 11 May 2004 09:22:29 +0100, Yu Song <(E-Mail Removed)> wrote or
>>> quoted :
>>>
>>>
>>>> It could be 100 times faster(depends on your connection) if you
>>>> read/write a chunk of data.
>>>
>>>
>>>
>>>
>>> There are two levels of overhead, talking to the socket, and talking
>>> to the buffered reader. Each kind of call has overhead. The bigger
>>> your buffer, the fewer calls to the underlying socket layer. If you
>>> are reading a giant chunk of raw bytes, DON'T use a
>>> BufferedInputStream. Use an unbuffered InputStream, and do it all in
>>> one giant I/O for maximum efficiency.
>>>
>>> see http://mindprod.com/jgloss/buffer.html for other hints on
>>> buffering.

>>
>>
>>
>> Roedy:
>>
>> I didn't think that unbuffered would be as good as buffered so I wrote
>> a couple of test programs and found that reading a whole array at a
>> time was faster than single bytes but that buffering single byte reads
>> was almost as good as buffered or multibyte. The difference between
>> buffered and unbuffered multibyte reads was small but unbuffered was
>> definitely faster.
>>
>> Here are my test programs.
>>
>> import java.io.*;
>> import java.net.*;
>> import java.util.*;
>>
>> public class TestServer {
>> public static void main(String[] args) {
>> byte[] b = new byte[1000];
>> Random r = new Random();
>> while (true) {
>> try {
>> ServerSocket ss = new ServerSocket(8192);
>> System.out.println("Waiting for a connection");
>> Socket s = ss.accept();
>> System.out.println("Connected to: " +
>> s.getInetAddress().getHostAddress());
>> ss.close();
>> OutputStream os = s.getOutputStream();
>> BufferedOutputStream bos = new BufferedOutputStream(os);
>> for (int i=0; i<5000; i++) {
>> r.nextBytes(b);
>> bos.write(b,0,b.length);
>> }
>> os.close();
>> s.close();
>> } catch (IOException ioe) {
>> System.out.println(ioe);
>> }
>> System.out.println("Done\n");
>> }
>> }
>> }
>>

>
>
> Because you know the exact data size you will receive.
>
> Try this client code below (similar to yours but the size of buffer is 512)
>
> //TestClient.java
> import java.io.*;
> import java.net.*;
>
> public class TestClient {
> public static void main(String[] args) {
> try {
> byte[] buf = new byte[512];
> int b;
> long start,stop;
> String host = (String)args[0];
> int port = Integer.parseInt(args[1]);
> Socket s = new Socket(host,port);
> InputStream is = s.getInputStream();
> System.out.println("Connected");
> BufferedInputStream bis = new BufferedInputStream(is);
> start = System.currentTimeMillis();
> while ((b = bis.read(buf)) != -1) ;
> stop = System.currentTimeMillis();
> System.out.println("Buffered, 512 bytes at a time: " +
> (stop - start) / 1000.0);
> bis.close();
> s.close();
> System.out.println("Done\n");
>
> s = new Socket(host,port);
> System.out.println("Connected");
> is = s.getInputStream();
> start = System.currentTimeMillis();
> while ((b = is.read(buf)) != -1) ;
> stop = System.currentTimeMillis();
> System.out.println("UnBuffered, 512 bytes at a time: " +
> (stop - start) / 1000.0);
> is.close();
> s.close();
> System.out.println("Done\n");
> } catch (Exception e) {
> System.out.println(e);
> }
> }
> }
>
>


Song:

Here are the results with your version of TestClient. Almost identical
to the 1000 byte buffer. Did you get a larger difference?

C:\JavaProjects\widgets>java SongTestClient 192.168.3.3 8192
Connected
Buffered, 512 bytes at a time: 42.656
Done

Connected
UnBuffered, 512 bytes at a time: 42.672
Done


C:\JavaProjects\widgets>

--

Knute Johnson
email s/nospam/knute/
Molon labe...
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
No "Wireless Network Connection" available in network connection =?Utf-8?B?am9raW5kYTE=?= Wireless Networking 7 10-16-2012 07:32 AM
Network did not assign network address Bill Babakian Wireless Networking 3 11-21-2004 08:15 PM
lost use of network printer connceted via wireless network after p =?Utf-8?B?Ul9DX0Jyb3duX0py?= Wireless Networking 0 11-05-2004 08:34 PM
My Network Places | Entire Network ?? Rush Wireless Networking 0 09-21-2004 09:43 PM
Network Computer Reboots when Laptop Connects to Wireless Network Charles Law Wireless Networking 7 09-14-2004 02:11 PM



Advertisments