Using bytes to save space. Does that really optimise perfomance or not?

I mean using primitive type for number (byte) instead of int/short/long.

If I would make an application with byte only, would that save any perfomance or space? Or its really NOT important? I thought I can make app just on bytes and it will be super optimized but maybe not? PS I know byte hold value just to 127(or128) but in certain applications thats enough

Short answer: no.

Longer answer: when you start to use a lot of bytes - like megabytes, typically in arrays, or buffers - then yes. But as class members? No. Don’t.

Cas :slight_smile:

Thank you Cas. Seems my idea was stupid haha

You can, and should, do the math yourself.

An int requires 32 bits. A byte requires 8 bits. So you’re saving 24 bits of memory by using a byte instead of an int.

Now, how many substitutions are we talking about here? If it’s 1000 substitutions (1 substitution in 1000 instances, 2 substitutions in 500, whatever), that’s 24 bits * 1000 = 24 kilobits, and we divide by 8 to get 3 kilobytes.

If you have a million substitutions in memory at once, then you’re saving 3 MB.

To put that in perspective, by default Java programs run with 256 MB of memory. So a million substitutions will save you about 1% of the allocated memory. (And you can increase this default memory allocation.)

This sounds like premature optimization: you’re thinking about making optimizations before you understand the numbers or see an actual problem. This is almost always a waste of time.

That being said, this kind of optimization does come in handy, if you have more than millions of int values that can be represented by smaller types.

But you shouldn’t just look for random “optimizations” before you understand the problem.

Edit: Another reason to consider which data type you should use is code readability. If a value will never go outside the bounds of a byte, then using a byte makes your code easier to understand. Of course, it can be very difficult to know that something will never happen. But code readability is more important than micro-optimizing your code.

An interesting question would also be whether a Java byte variable only consumes 1 byte or is aligned on 4- or 8 byte border, meaning you wouldnt save nothing.

Array elements inside a byte[] array occupy 1 byte and are 1-byte aligned.
The alignment of class members can be analyzed quickly via OpenJDK JOL.
For the following class declaration:


class A {
    byte a;
    byte b;
    byte c;
    int d;
    byte e;
    int f;
    float g;
    long h;
    long i;
}

it outputs on a 1.8_141 64-bit HotSpot JVM:


# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

test.Align$A object internals:
 OFFSET  SIZE    TYPE DESCRIPTION                               VALUE
      0    12         (object header)                           N/A
     12     4     int A.d                                       N/A
     16     8    long A.h                                       N/A
     24     8    long A.i                                       N/A
     32     4     int A.f                                       N/A
     36     4   float A.g                                       N/A
     40     1    byte A.a                                       N/A
     41     1    byte A.b                                       N/A
     42     1    byte A.c                                       N/A
     43     1    byte A.e                                       N/A
     44     4         (loss due to the next object alignment)
Instance size: 48 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

So you can indeed save storage by using byte fields, but it is delicate, since you also have to take care to end your class fields on a 8-byte boundary (for a 64-bit JVM which uses compressed oops). So if your class consists of only 1 byte field it’ll occupy exactly as much memory as if you had 1 int field, to make it end on the 16-byte boundary.

So in the end: It is not worth the trouble.

Its good Idea - and Bad Implication in Java (not your fault ^^)
p.s I use byte when i can - without paranoia (all int -> short -> byte) XD

For big Data consuming - its nice to pack data to ByteBuffer Object - and clean its manualy
if you let say have 10mil objects with 38 byte each +12 byte Object Header + 6 Align x64 = overhead is 180 mb
But 10 mil objects - is rare (and its only 180 mb+, another problem is GC)