1

Is it possible to index a Java array based on a byte?

i.e. something like

array[byte b] = x;

I have a very performance-critical application which reads b (in the code above) from a file, and I don't want the overhead of converting this to an int. What is the best way to achieve this? Is there a performance-decrease as a result of using this method of indexing rather than an int?

With many thanks,

Froskoy.

4
  • 1
    I can't speak to the performance issue. If you want this I'd use a ByteBuffer and iterate through it. ByteBuffer is pretty optimized... You could also use a direct ByteBuffer Commented Sep 27, 2012 at 21:49
  • Have you tried it? Hint - it compiles... Commented Sep 27, 2012 at 21:50
  • 4
    If you're reading from a file on a physical disk (even an SSD), then conversions from byte to int are going to be utterly insignificant compared with the path it takes to get the data out in the first place. Commented Sep 27, 2012 at 21:52
  • 1
    I wouldn't assume there is a significant performance hit until you have measured it and it causing a problem for you program. Worry about performance when its isn't a problem leads to poor design choices. Commented Sep 27, 2012 at 21:57

4 Answers 4

6

There's no overhead for "converting this to an int." At the Java bytecode level, all bytes are already ints.

In any event, doing array indexing will automatically upcast to an int anyway. None of these things will improve performance, and many will decrease performance. Just leave your code using an int.

The JVM specification, section 2.11.1:

Note that most instructions in Table 2.2 do not have forms for the integral types byte, char, and short. None have forms for the boolean type. Compilers encode loads of literal values of types byte and short using Java virtual machine instructions that sign-extend those values to values of type int at compile-time or runtime. Loads of literal values of types boolean and char are encoded using instructions that zero-extend the literal to a value of type int at compile-time or runtime. Likewise, loads from arrays of values of type boolean, byte, short, and char are encoded using Java virtual machine instructions that sign-extend or zero-extend the values to values of type int. Thus, most operations on values of actual types boolean, byte, char, and short are correctly performed by instructions operating on values of computational type int.

Sign up to request clarification or add additional context in comments.

5 Comments

"all bytes are already ints" Won't it have to do sign extension to fill the extra bits on the upcast? Or is there some other mechanism that I'm not aware of?
The sign extension is already there. As soon as you have a method-local variable that's a byte, it's actually implemented as an int.
Interesting, I didn't know that. Do you happen to know a JLS citation for that? J/w, it's fine if you don't, I can investigate it myself tonight.
I updated my answer with an actual demonstration from real code.
As far as I understood his question, he meant accessing any type of array with a byte variable, such as Object[] objs; byte b; ... Object obj = objs[b]; However, from your example, it seems that it doesn't matter, it'll result in the same behavior anyway. Thanks +1
3

As all integer types in java are signed you have anyway to mask out 8 bits of b's value provided you do expect to read from the file values greater than 0x7F:

byte b;
byte a[256];
a [b & 0xFF] = x;

Comments

0

No; array indices are non-negative integers (JLS 10.4), but byte indices will be promoted.

3 Comments

But "Arrays must be indexed by int values; short, byte, or char values may also be used as index values because they are subjected to unary numeric promotion (§5.6.1) and become int values. "
@Zoe So it's indexed by an int--but I could have been clearer.
I think you had it. just a bit terse to understand.
0

No, there is no performance decrease, because on the moment you read the byte, you store it in a CPU register sometime. Those registers always works with WORDs, which means that the byte is always "converted" to an int (or a long, if you are on a 64 bit machine).

So, simply read your byte like this:

int b = (in.readByte() & 0xFF);

If your application is that performance critical, you should be optimizing elsewhere.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.