Trove4j的TObjectIntHashMap与EnumMap<Enum, Integer>比较

3

通常人们会说,在键为枚举类型时我们应该使用EnumMap。但是,如果我想计算每个枚举值的频率呢?在这种情况下,似乎使用Trove4j的TObjectIntHashMap更好。

以下是使用Trove4j集合的示例:

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

对于EnumMap,代码如下:

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);
}

因此,trove4j在内部检查存在性并可以自动增加值,这使得代码更简洁。使用枚举作为键的EnumMap具有更高的性能,但获取和增加Integer(装箱和拆箱)也需要时间。
如果考虑低内存成本和快速速度,哪种方法更好?

覆盖或包装EnumMap,您的代码将更加简洁。 EnumMap几乎肯定更快,因为它针对Enum进行了优化。Trove映射用于一般的Object,因此没有这些优化。 - Boris the Spider
@BoristheSpider 同样的道理,Trove 优化了 int 值并且不需要包装器。你需要测试特定的用例来确定哪个更好。我相信数组比两者都要好。 - Peter Lawrey
@PeterLawrey 我觉得这个说法站不住脚。我认为哈希和查找的成本是耗费时间的,而不是卫星数据的存储。 - Boris the Spider
1
@BoristheSpider 相对于创建对象的成本(如果计数足够高以执行此操作),基于 int 值的哈希是微不足道的。在 Trove Map 中使用条目的成本可能非常昂贵,尤其是对于较低的计数。 - Peter Lawrey
1个回答

4

如果你想要更低的成本/更快的速度,你可以使用普通数组。

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

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

 // to count.
 counts[e.ordinal()]++;

聪明的做法当然是拥有最小的开销。 - Boris the Spider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接