Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Byte-size enum in Java

I have a class of which there may be many instances (on a mobile device), so I'm trying to minimize the size. One of my fields is a "DrawTarget" that indicates whether drawing operations are being ignored, queued to a path or drawn to the display. I would like it to take a single byte or less since there are only 3 possible values, but I would also like it to be friendly code so I don't have hard-coded numbers all over. One thought is to use an enum like:

public enum DrawTarget {
    Invisible,
    Path,
    Canvas
}

But from what I read, a Java enum doesn't allow you to specify the memory layout -- I can't request that the enum values represent a byte-size value -- and I guess enum values end up being integer-sized values in Java.

So I thought about maybe making an implicit conversion operator in the enum... is this possible in Java? Or is my best option to implement something like this within the enum:

public static DrawTarget fromValue(byte value) {
    switch (value) {
    case 0:
        return Invisible;
    case 1:
        return Path;
    default:
        return Canvas;
    }
}

and then call DrawTarget.fromValue wherever I want to access the value?

Or should I just create a single-byte class since apparently (from what I read in my research on this) enums are basically just special classes in Java anyway?

public class DrawTarget {
    public static final byte Invisible = 0;
    public static final byte Path = 1;
    public static final byte Canvas = 2;
}

But how to I represent the value of an enum instance if I use that last solution? I still need a way to allow the "=" operator to accept one of the static fields of the class... like a conversion constructor or an assignment operator overload.

I suspect, however, that any class object, being a reference type, will take more than a byte for each instance. Is that true?

like image 810
BlueMonkMN Avatar asked Mar 03 '13 13:03

BlueMonkMN


People also ask

How many bytes is an enum Java?

This means that an enum reference costs as much as any other object reference, usually four bytes.

What is the size of enum in bytes?

The size is four bytes because the enum is stored as an int . With only 12 values, you really only need 4 bits, but 32 bit machines process 32 bit quantities more efficiently than smaller quantities.

What is the size of enum in Java?

On an 8-bit processor, enums can be 16-bits wide. On a 32-bit processor they can be 32-bits wide or more or less. The GCC C compiler will allocate enough memory for an enum to hold any of the values that you have declared. So, if your code only uses values below 256, your enum should be 8 bits wide.

Are enums 32 bit?

Default. The default is -fno-short-enums . That is, the size of an enumeration type is at least 32 bits regardless of the size of the enumerator values.


3 Answers

In Java enum is a class that has as many instances, as there are values. The instances are produced at class (enum) loading time. Each place where you use an enum variable or an enum attribute, you actually use an ordinary reference to one of the existing enum objects (instances of enums are never created after enum is initialized).

This means that an enum reference costs as much as any other object reference, usually four bytes. Which is really, really, really little.

  1. You don't know how much memory does a byte take (really! remember that low level memory management includes plenty of padding!), so any "optimization" based on this will fail. On a given architecture a byte field might take as much memory as an integer field (because it might be faster that way).

  2. If you want to write good Java, use enum. Really. The only good reason not to use enums, would be if you had a whole array of values, like: drawTargets[] = new DrawTarget[100000];

  3. If you insist on microoptimizing, just use plain bytes and forget enums; public static final byte SOMETHING = 1; is fine for making comparisons (and sucks for debugging).

I have written Android programs for a long time and have never seen such microoptimization pay off. Your case might be the one in a million, but I don't think it is.

Also, to make life simpler for all of us, please consider using Java conventions in Java code: enum instances and public final static fields should be names LIKE_THIS, attributes likeThis (not LikeThis!).

like image 178
fdreger Avatar answered Oct 06 '22 22:10

fdreger


and I guess enum values end up being integer-sized values in Java.

No, enums are always classes in Java. So if you have a field of type DrawTarget, that will be a reference - either to null or to one of the three instances of DrawTarget. (There won't be any more instances than that; it's not like a new instance of DrawTarget is created every time you use it.)

I would go with the enum and then measure the memory usage - an enum is logically what you want, so take the normal approach of writing the simplest code that works and then testing the performance - rather than guessing at where bottlenecks might be.

You may want to represent the value as a single byte when serializing, and then convert it back to the enum when deserializing, but other than that I'd stick with the enum type throughout your code if possible.

like image 40
Jon Skeet Avatar answered Oct 06 '22 22:10

Jon Skeet


Unless android has some special way of treating enum references, each reference to a DropTarget will indeed take more than one byte in memory. Enums are classes, and enum instances are objects. So a reference to an enum instance takes the same amout of memory as any other object reference.

I wouldn't care much about it unless you have measured that this caused memory problems, though, and that reducing the size would have a significant impact.

What you get from enums, mainly, is type safety. If a method takes a DropTarget as argument, you (or coworkers) won't be able to pass anything other than one of the three instances of DropTarget (or null). If you use a byte instead, the code is less clear, and anyone could pass any byte value instead of the three authorized byte values.

So, decide which is the most important for you, and choose the solution you prefer.

like image 40
JB Nizet Avatar answered Oct 06 '22 22:10

JB Nizet