
Signature
And loving it,
-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)
> I am stuffing a byte[] with byte, short and int values and then
> reconstituting them elsewhere. Everything works fine but I am concerned
[quoted text clipped - 5 lines]
> buffer[index++] = (byte)(((short)x & 0xFF00) >> 8);
> buffer[index++] = (byte)( (short)x & 0x00FF);
The (short) casts are unnecessary unless `x' is a float
or a double. Also, you can get rid of the masks and just
rely on the (byte) casts:
buffer[index++] = (byte)(x >> 8);
buffer[index++] = (byte)x;
... but you'll probably need to do this to quite a large
number of values before you see a measurable speed change.
> The code to reconstitute the short looks like this:
>
[quoted text clipped - 3 lines]
> short bs = b < 0 ? (short)((b & 0x7F) + 128) : b;
> x = (short)((as << 8) | bs);
You're working too hard. Try
short x = (short)(buffer[index++] << 8);
x += buffer[index++] & 0xFF;
You could even pack all of this into one statement like
short x = (short)((buffer[index++] << 8)
+ (buffer[index++] & 0xFF));
... but this is cringe-inducing to old C programmers
like me. (Even though javac knows how to organize the
side-effects, there's no point in giving the maintenance
programmer a chance to make a "harmless" rearrangement.)
> Is this the most efficient way of doing this?
Maybe, maybe not, and maybe the answer is different on
different systems. How much will you suffer if it turns
out to be only the second- or third-most efficient?
> I find it annoying that
> bytes are signed.
So do I. I also find it annoying that mosquitoes bite,
but I learn to get along anyhow.
> I am also concerned that it may not work for all
> short values.
As far as I can tell, both the originals and the rewrites
should work for all values. But since there are only 65536
short values, you could easily write a little test program
to pack and unpack all of them and report any discrepancies.

Signature
Eric Sosman
esosman@ieee-dot-org.invalid
Patricia Shanahan - 04 Oct 2007 14:39 GMT
...
>> byte a = buffer[index++];
>> byte b = buffer[index++];
[quoted text clipped - 6 lines]
> short x = (short)(buffer[index++] << 8);
> x += buffer[index++] & 0xFF;
...
>> Is this the most efficient way of doing this?
>
> Maybe, maybe not, and maybe the answer is different on
> different systems. How much will you suffer if it turns
> out to be only the second- or third-most efficient?
There is a risk that the conditional branch version will be slow on deep
pipeline processors for mixed sign data. Each conditional branch that is
not correctly predicted causes a pipeline flush, and subsequent delay
while the correct code works its way though the pipeline.
This seems to me to be a case where the simpler, cleaner code is also
likely to be the more efficient, if there is any difference.
Patricia
Qu0ll - 04 Oct 2007 15:18 GMT
Thank you Eric for your very useful reply. Comments inline...
> The (short) casts are unnecessary unless `x' is a float
> or a double. Also, you can get rid of the masks and just
[quoted text clipped - 5 lines]
> ... but you'll probably need to do this to quite a large
> number of values before you see a measurable speed change.
Yes, I see now the unnecessary nature of the (short) casts and masks. It's
much simpler and easier to maintain this way and makes the task of stuffing
int values easy too.
> You're working too hard. Try
>
> short x = (short)(buffer[index++] << 8);
> x += buffer[index++] & 0xFF;
This will do nicely. I need to do some processing between accesses to the
buffer so this works better for me than the more concise solution you also
suggested.
> Maybe, maybe not, and maybe the answer is different on
> different systems. How much will you suffer if it turns
> out to be only the second- or third-most efficient?
It doesn't really matter whether it's an order of magnitude more efficient
or not. What matters is that it's simpler and that I have learned something
in the process.
> As far as I can tell, both the originals and the rewrites
> should work for all values. But since there are only 65536
> short values, you could easily write a little test program
> to pack and unpack all of them and report any discrepancies.
While I haven't run this exact test, I have run the application with a vast
selection of values and it has proven to be 100% reliable.
Thanks again!

Signature
And loving it,
-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)
> I am stuffing a byte[] with byte, short and int values and then
> reconstituting them elsewhere. Everything works fine but I am concerned
[quoted text clipped - 17 lines]
> bytes are signed. I am also concerned that it may not work for all
> short values.
Have you looked into using a ByteBuffer?
<http://java.sun.com/j2se/1.5.0/docs/api/java/nio/ByteBuffer.html>
It has putInt, putLong, putShort, putChar, putDouble, etc....
You can use ByteBuffer.wrap(bufferArray) too.
HTH.

Signature
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
Qu0ll - 04 Oct 2007 19:37 GMT
> Have you looked into using a ByteBuffer?
> <http://java.sun.com/j2se/1.5.0/docs/api/java/nio/ByteBuffer.html>
> It has putInt, putLong, putShort, putChar, putDouble, etc....
>
> You can use ByteBuffer.wrap(bufferArray) too.
Yes, I see now that ByteBuffer does pretty much what I was trying to do but
I am going to stick with the original approach (and Eric's improvements)
because it works, it is as efficient as it can be and all this is happening
inside an applet where I am trying to limit the number of classes being
loaded.
But thanks for the suggestion (also to Nigel for suggesting same).

Signature
And loving it,
-Q
_________________________________________________
Qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email me)
> I am stuffing a byte[] with byte, short and int values and then
> reconstituting them elsewhere. Everything works fine but I am concerned
[quoted text clipped - 16 lines]
> Is this the most efficient way of doing this? I find it annoying that bytes
> are signed. I am also concerned that it may not work for all short values.
Have you considered using ByteBuffer? It is designed to do exactly this kind of
thing. Whether it is more efficient is another matter entirely, but it ought to
be simpler and your intention should be more transparent.

Signature
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : nmw@ion.le.ac.uk
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
>I am stuffing a byte[] with byte, short and int values and then
>reconstituting them elsewhere. Everything works fine but I am concerned
>that I am not doing it as efficiently as possible.
You can use a DataOutputStream to a ByteArrayStream. Sun is going to
write pretty good code. You can also peek at how Sun does it by
looking up the code in src.zip or letting your IDE find it for you.
I have similar code in LEDataStream doing the same thing for little
endian binary data.
See http://mindprod.com/products.html#LEDATASTREAM

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
> I am stuffing a byte[] with byte, short and int values and then
> reconstituting them elsewhere. Everything works fine but I am concerned
> that I am not doing it as efficiently as possible.
Efficiency is in the eyes of the beholder - the code you've written is very
efficient in terms of economy of memory usage, but fails to be efficient when
the code needs to be maintained, as it is relatively difficult to deduce the
purpose of stuffing these three values into one. This loss of efficiency may
end up costing you more in the long run - what happens when a junior coder is
tasked with adding a fourth value into the composed collection of values.
If your purpose is to return three values as one from a method call, then I
would recommend that you create a small private inner class that contains
each of the three individual values that you need to return as instance
fields, and that you return an object of this class instead of performing
these gymnastics.
Cheers!
GRB

Signature
---------------------------------------------------------------------
Greg R. Broderick usenet200709@blackholio.dyndns.org
A. Top posters.
Q. What is the most annoying thing on Usenet?
---------------------------------------------------------------------