slashms
slashms

Reputation: 978

HashMap vs EnumMap scenario

I am in a dilemma between 2 ways of implementing something and wondered what is more efficient (memory and\or time wise).

I need to get requests containing an Op-code and map it to a Category. There are between 1000 to 2000 Op-codes only 3-4 categories. The mapping is predefined and well known.

Solution 1: using HashMap<Integer, Category> It's simple but I think it's wasting too much memory because its many to few mapping.

Solution 2: Predefine an Enumartion:

public enum CategoryEum{
C1("123", "456",....),
C2("777","888",...) 
... }

And then using this enum for a:

EnumMap<CategoryEnum, Category>

I read that EnumMap is compact and efficient.

Important note: The Maps in both solutions are initiated once and doesn't change throughout the process life.

What do you think?

Upvotes: 2

Views: 5731

Answers (2)

Lukas Eder
Lukas Eder

Reputation: 220877

Consecutive op codes

If your op-codes are consecutive integers between 0 and 2000, you don't need a map. Use the op-codes as indexes of an array, like so (do note that the hard-coding is for sake of example brevity only):

Category[] mapping = {
    Category.A, // Opcode 0
    Category.A, // Opcode 1
    Category.B, // Opcode 2
    ...
};

int opcode = ...
Category category = mapping[opcode];

Sparse op codes

If your op-codes are not consecutive and sparse (with large gaps), your enum solution might work as you could encode the op-codes as enum and use the enum ordinal for the array index:

Category[] mapping = {
    Category.A, // Opcode 13 (the first possible opcode)
    Category.A, // Opcode 42 (the second possible opcode)
    Category.B, // Opcode 88 (the third possible opcode)
    ...
};

int opcode = opcodeEnum.ordinal();
Category category = mapping[opcode];

Note that in the latter case, EnumMap is pretty much doing the exact same thing as the above solution although using up more memory, as it contains some caches for Map.entrySet() and other calls.

When to prefer the above over HashMap

In any case, the array or EnumMap solutions should be preferred over the HashMap solution if you will provide a category for every op code in the possible op code space. If you only categorise 1% of your op codes, then creating the array for the entire op code space will be wasting too much memory, and a HashMap might be better.

Upvotes: 3

Radiodef
Radiodef

Reputation: 37845

Solution 1: using HashMap<Integer, Category> It's simple but I think it's wasting too much memory because its many to few mapping.

Actually, it's probably no more than 10-20KB which is barely a crumb these days. The HashMap is just an array of pointers.

However, if you're converting int to Integer all the time, that's probably not the best thing in the world.

EnumMap<CategoryEnum, Category>

I don't think this actually helps you out, because now you need to map opcodes to CategoryEnum.

If the numerical values of the opcodes aren't very large (a few thousand), then by far the best option is just to use a Category[] and index the opcodes in to the array directly. The length of the array needs to be the value of the highest opcode +1.

If the numerical values are more than a few thousand, then it isn't that difficult to program your own simple hashtable, just for retrievals. (DIY is kind of like Java heresy, but until they give us primitive generics we are stuck.)

There are some libraries out there with primitive collections as well.

Upvotes: 1

Related Questions