views:

85

answers:

2

I'm working on an Android application (in Java, obviously) and I recently updated my UDP reader code. In both versions, I set up some buffers and receive a UDP packet:

byte[] buf = new byte[10000];
short[] soundData = new short[1000];
DatagramPacket packet = new DatagramPacket (buf, buf.length);
socket.receive (packet);

In the initial version, I put the data back together one byte at a time (it's actually 16 PCM audio data):

for (int i = 0; i < count; i++)
    soundData[i] = (short) (((buf[k++]&0xff) << 8) + (buf[k++]&0xff));

In the updated version, I used some cool Java tools I didn't know about when I started:

bBuffer  = ByteBuffer.wrap (buf);
sBuffer  = bBuffer.asShortBuffer();
sBuffer.get (soundData, 0, count);

In both cases, "count" is being populated correctly (I checked). However, there appear to be new problems with my streaming audio -- perhaps it isn't being handled fast enough -- which doesn't make any sense to me. Obviously, the buffer code is compiling into a lot more than three statements of JVM code, but it sure seemed like a reasonable assumption when I start this that the 2nd version would be faster than the 1st.

Patently, I'm not insisting that my code HAS to use Java NIO buffers, but at first glance at least, it DOES seem like a mo' betta' to go about this.

Anybody got any recommendations for a fast, simple Java UDP reader and whether there is a generally accepted "best way"??

Thanks, R.

A: 

In general, working with primitive types directly is going to be more efficient than working with objects because you avoid some of the overhead of creating objects, function calls, etc.

There are reasons to use the utility objects other than speed: convenience, safety, etc.

The best way to test the difference in this particular case would be to actually measure it. Try out both methods with a large dataset and time it. Then, you can decide if it is worth the benefits in this case.

You can also use Android's profiler to see where your problems really are. See TraceView.

Mayra
I seem to have touched off a religious war... Sorry about that, and thanks for the rationality.
Rich
fadden
A: 

I would use DataInputStream for this task, wrapped around a ByteArrayInputStream wrapped around the byte array. Encapsulates the shifting in readShort() without the overheads of ByteBuffer.

Alternatively you could read directly into a DirectByteBuffer via a DatagramChannel, rather than using DatagramPacket & DatagramSocket. At present you're using a mixture of java.net and java.nio.

I wouldn't expect major performance differences between these two approaches, but I would expect them both to be faster than your hybrid approach.

EJP