Our java program uses socket to send a lot of data out, and the types of
these data are integer, long, and string. Before we send them out, we
have to transform integers, long, and string to a byte array(correct me,
if it is *not* necessary), and then send them out like this,
socket.getOutputStream().write(datas);
socket.getOutputStream().flush();
After some profiling, we find the performance bottleneck of our program
is in Util.int2bytes(int), which is called nearly 500,000 times,
public static byte[] int2bytes(int nNum)
{
byte[] bytesRet = new byte[4];
bytesRet[0] = (byte) ((nNum >> 24) & 0xFF);
bytesRet[1] = (byte) ((nNum >> 16) & 0xFF);
bytesRet[2] = (byte) ((nNum >> 8) & 0xFF);
bytesRet[3] = (byte) (nNum & 0xFF);
return bytesRet;
}
I also find that the "new" statement is very expensive. How could I
tune my program?
Another bottleneck is located on the socket write and flush. How could
I make socket part in my program efficient? Any comments are welcome.
Best Regards

Signature
Yao Qi <qiyaoltc AT gmail DOT com> GNU/Linux Developer
http://duewayqi.googlepages.com/
linux: No such file or directory
David Portabella - 09 Sep 2007 16:17 GMT
> Our java program uses socket to send a lot of data out, and the types of
> these data are integer, long, and string. Before we send them out, we
[quoted text clipped - 30 lines]
>
> linux: No such file or directory
You are currently doing:
+++++++
OutputStream out = socket.getOutputStream();
out.write(int2bytes(nNum));
+++++++
To avoid the new operation, you could replace it by:
+++++++++++++
OutputStream out = socket.getOutputStream();
writeInteger(nNum, out);
public static void writeInteger(int nNum, OutputStream)
{
out.write((byte) ((nNum >> 24) & 0xFF));
out.write((byte) ((nNum >> 16) & 0xFF));
out.write((byte) ((nNum >> 8) & 0xFF));
out.write((byte) (nNum & 0xFF));
}
+++++++++++++
However, you would need to provide also this function for the other
data types.
+++++++++++++++++++++++++++
I suggest using the DataOutputStream object, which handles data types:
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(nNum);
See:
http://java.sun.com/j2se/1.5.0/docs/api/java/io/DataOutputStream.html
HTH,
DAvid
Lew - 09 Sep 2007 17:37 GMT
Yao Qi wrote:
>> I also find that the "new" statement is very expensive.
How did you find that?
Which JVM are you using?
In many JVMs the "new" operation is not very expensive, on the order of a
dozen machine cycles.

Signature
Lew
Roger Lindsjö - 09 Sep 2007 19:12 GMT
> Our java program uses socket to send a lot of data out, and the types of
> these data are integer, long, and string. Before we send them out, we
[quoted text clipped - 6 lines]
> After some profiling, we find the performance bottleneck of our program
> is in Util.int2bytes(int), which is called nearly 500,000 times,
<snip code>
> Another bottleneck is located on the socket write and flush. How could
> I make socket part in my program efficient? Any comments are welcome.
Instead of writing directly to the socket output stream, wrap it in a
BufferedStream which keeps an internal byte array, and then just write
your output to it, byte by byte.
Your code could then look like:
buffered.write(nNum >> 24);
buffered.write(nNum >> 16);
buffered.write(nNum >> 8);
buffered.write(nNum);
Once you are done with your data, call buffered.flush() to ensure all is
sent. This way you don't have to create so many intermediate byte arrays
and also you will probably lower the number of network packets sent.
//Roger
Martin Gregorie - 09 Sep 2007 23:17 GMT
> Instead of writing directly to the socket output stream, wrap it in a
> BufferedStream which keeps an internal byte array, and then just write
> your output to it, byte by byte.
Another way of avoiding overheads (and getting a handle on the number of
writes to the socket) is to use a message-oriented protocol and assemble
each message in a StringBuffer or byte array before sending it using an
unbuffered stream. Same applies to reading.
Unlike the direct use of Input and Output streams, this method allows
you to threading to overlap message assembly/disassembly with i/o.

Signature
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
Roedy Green - 13 Sep 2007 02:04 GMT
>public static byte[] int2bytes(int nNum)
>{
[quoted text clipped - 5 lines]
> return bytesRet;
>}
you could use LEDataStream.
see http://mindprod.com/products.html#LEDATASTREAM
it allocates its byte-sex swap work buffer at file open time, and
reuses it.
You also might consider GZIPing your stream.
See http://mindprod.com/jgloss/gzip.html
http://mindprod.com/applet/fileio.html

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com