Reputation: 4679
I had a java game book recommend implementing all data as Int when possible, that that type runs the fastest. It said the Byte, Char, and Boolean are implemented as Int anyway, so you don't save space and the casting you end up having to do in the code because of the Byte data will slow it down. For instance, a cast is needed for
a = (byte)(b+c);
since the addition result is an Int, even when a,b, and c are all declared as Bytes.
I currently have a huge 2D array declared as Byte for my game, to save space and for bitwise operations. Is it actually saving space? I've also seen bitwise operations done on Ints in examples, do bitwise operations work as expected on Ints?
Upvotes: 4
Views: 252
Reputation: 10020
The answer depends on whether you are working with a single variable of type byte
or with a byte array, byte[]
. A byte array does indeed save space, with each Java byte using just a byte of memory (plus a constant amount of housekeeping data for the array object). However, a single local variable of type byte
is actually stored as an int
on the stack and takes the corresponding 4 bytes of memory. This is even expressed in the bytecode - there is the opcode baload
- "Load byte or boolean from array" but there is no opcode for loading a byte from local variable like there is iload
for ints. Similarily, local char
and boolean
variables actually are stored on the stack as an int and int
-based opcodes are used to access them.
The entry 2.6.1 in JLS also says that all local variables take either one or two "slots" on the stack, so the single-slot types byte, char, float and int all take the same space. The JVM cannot address a unit smaller than a single such slot, so in the case of a byte, 3 bytes are so to say wasted.
To wrap it up: do use byte
arrays to save space, but in the case of individual variables, using a byte
instead of int
won't save space and may even have a small negative performance impact (it may however be required if you need byte
for the semantics, e.g. counter wrapping behavior and such).
Upvotes: 1
Reputation: 129587
This is generally incorrect. In fact, this is outlined in the JVM Specification §2.3:
The primitive data types supported by the Java Virtual Machine are the numeric types, the
boolean
type (§2.3.4), and thereturnAddress
type (§2.3.3).The numeric types consist of the integral types (§2.3.1) and the floating-point types (§2.3.2).
The integral types are:
byte
, whose values are 8-bit signed two's-complement integers, and whose default value is zero
short
, whose values are 16-bit signed two's-complement integers, and whose default value is zero
int
, whose values are 32-bit signed two's-complement integers, and whose default value is zero
long
, whose values are 64-bit signed two's-complement integers, and whose default value is zero
char
, whose values are 16-bit unsigned integers representing Unicode code points in the Basic Multilingual Plane, encoded with UTF-16, and whose default value is the null code point ('\u0000'
)
Now, for boolean
it's slightly a different story. From §2.3.4:
Although the Java Virtual Machine defines a
boolean
type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely dedicated to operations onboolean
values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machineint
data type.
You can see differences in the bytecode depending on whether you use a byte[]
or an int[]
, so they're not identical:
byte[] b = {42};
ICONST_1 NEWARRAY T_BYTE DUP ICONST_0 BIPUSH 42 BASTORE ASTORE 1
vs
int[] b = {42};
ICONST_1 NEWARRAY T_INT DUP ICONST_0 BIPUSH 42 IASTORE ASTORE 1
Is it actually saving space?
Yes, it likely is, especially if the array is very large.
do bitwise operations work as expected on Ints?
Yes, they do.
Upvotes: 6
Reputation: 1179
Yes, when you perform a byte addition the return value is always an integer, reason being that 8bit + 8bit addition can always result in a value which is greater than 8bit.
e.g.
255 | 1111 1111
121 | 0111 1001
376 | 1 0111 1000
So if you try to store it in a byte again will definitely result in loss of data. Instead of 376 you would get "120" if typecasting to byte is done.
You can definitely use int instead of byte and also the bit wise operations work perfectly on int. refer: http://www.tutorialspoint.com/java/java_bitwise_operators_examples.htm
Upvotes: 0
Reputation: 59343
It is true that byte + byte = int
, requiring a cast, but byte
s are implemented with 8 bits of data in memory, while int
s are 32 bits. Therefore, using byte
s will decrease the amount of memory that an array takes up by 4 times.
For example, if you had a 10 by 10 array of byte
s, its size would be 800, but a 10 by 10 array of int
s' size would be 3200.
Upvotes: 1