Introduction
If you are familiar with struct
s (value types), you may have wondererd why Java does not support them yet. While objects in Java are great for common usage, in those cases where performance and memory really matters, struct
s would be ideal.
Background
To illustrate the benefits of value types, consider the following:
int[] arrayA = new int[1000];
Integer[] arrayB = new Integer[1000];
Both arrayA
and arrayB
store 1000 integers. Since each integer in Java takes 4 bytes, the total storage should be close to 4000 bytes. For arrayA
, this is true
, including the array header, arrayA
takes approximately 4016 bytes. However, things are not similar for arrayB
, which stores an array of references to objects. ArrayB
takes 20016 bytes assuming each reference takes four bytes.
What if we have a class representing a vector?
class Vector2f { float x, y; }
Vector2f[] arrayVec = new Vector2f[1000];
We are interested in storing 1000 vectors, which should ideally take about 8000 bytes of memory.
However, since Vector2f
is a class, we get to a similar issue as with the int
and Integer
. ArrayVec
takes ~28016 bytes, which is a lot more from the original 8000 which will be used by our application.
Not only memory, but also performance is affected by the object overhead as the processor will have to load a lot more data. We could store the thousand vectors in a primitive array, however, what can we do for data such as?
class Star { int id; double x, y; float absMag; }
Star[] starArray = new Star[1000];
Each star has 24 bytes of data, with object header of 12 bytes we get 36 bytes and with alignment 40 bytes. Star array takes ~44016 bytes.
We could store the star data as:
int[] starId = new int[1000];
double[] starXY = new double[2000];
float[] starAbsMag = new float[1000];
This would bring the memory usage down to 24048 bytes. However, how readable and maintainable would our code look like.
Luckily, there is an alternative.
Using the Code
With the help of an open source library JUnion, we can write the following:
@Struct
class Star { int id; double x, y; float absMag; }
Star[] starArray = new Star[1000];
Since Star is no longer an object, starArray
uses ~24040 bytes.
We can use the struct
type Star
in a very similar way as we use Java objects. There are few distinctions such as struct
array elements that are not initialized with constructors as normal object arrays are.
Star[] starArray = new Star[1000];
starArray[5].id = 10;
Star s5 = star[5];
...
If Star
was an object, the above code would throw a NullPointerException
. This is not the case for struct
types.
To use struct
types, you will require https://github.com/TehLeo/junion.
Conclusion
This article introduces struct/value types and their benefits of lower memory usage over objects.