3

Usually people say we should use EnumMap when the key is an enum. But what about this case I want to count the frequencies of each enum value, it seems like trove4j TObjectIntHashMap is better in code.

The following is the example with trove4j collection:

TObjectIntMap<ExtraOperator> extraOpr = new TObjectIntHashMap<ExtraOperator>();
extraOpr.adjustOrPutValue(ExtraOperator.ternary, 1, 1);

In case of EnumMap, the code looks like:

Map<ExtraOperator, Integer> extraOpr = Maps.newEnumMap(ExtraOperator.class);
if (extraOpr.containsKey(ExtraOperator.ternary)) {
    extraOpr.put(ExtraOperator.ternary, extraOpr.get(ExtraOperator.ternary) + 1);
} else {
    extraOpr.put(ExtraOperator.ternary, 1);
}

So, trove4j checks existence internally and can auto-increment the value, which makes the code more concise. EnumMap use enum as key has higher performance but the retrieval and increment of the Integer(boxing and unboxing) also cost time.

Which one would be better if we consider low memory cost and fast speed?

Xiansong
  • 91
  • 2
  • 8
  • Override or wrap the `EnumMap` and your code will be more concise. The `EnumMap` is almost certainly faster because it is optimised for `Enum`s. The `Trove` map is for general `Object`s and so does not have those optimisations. – Boris the Spider Aug 11 '13 at 14:45
  • @BoristheSpider By the same argument, Trove is optimised for `int` values and does need wrappers. You would have to test for a given use case to determine which is better. I believe an array will be better than either. – Peter Lawrey Aug 11 '13 at 18:02
  • @PeterLawrey I don't think that holds water. I think the hashing and lookup costs time not the storage of the satellite data... – Boris the Spider Aug 11 '13 at 20:41
  • 1
    @BoristheSpider A hash of an int based value is trivial compared with the cost of creating objects (if it the count gets high enough to do this) The cost of using Entries in the trove map might be just expensive esp for lower counts. – Peter Lawrey Aug 11 '13 at 20:46

1 Answers1

4

If you want lower cost/faster you could use a plain array.

 static final ExtraOperator[] VALUES = ExtraOperator.values();

 private final int[] counts = new int[VALUES.length];

 // to count.
 counts[e.ordinal()]++;
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130