我希望这个问题对于这个论坛来说不会被认为太基础,但我们会看到。我想知道如何重构一些代码以获得运行多次的更好性能。
假设我正在使用 Map(可能是 HashMap)创建一个词频列表,其中每个键都是一个字符串,其中包含要计算的单词,值是一个整数,每次找到单词的标记时都会递增。
在 Perl 中,递增这样的值非常容易:
$map{$word}++;
但在 Java 中,它要复杂得多。这是我目前正在做的方式:
int count = map.containsKey(word) ? map.get(word) : 0;
map.put(word, count + 1);
这当然依赖于较新 Java 版本中的自动装箱功能。我想知道您是否可以建议一种更有效的方法来增加这种价值。是否有更好的性能理由来避开 Collections 框架并使用其他东西来代替?
更新:我已经对几个答案进行了测试。见下文。
原文由 gregory 发布,翻译遵循 CC BY-SA 4.0 许可协议
部分测试结果
对于这个问题,我已经得到了很多很好的答案——谢谢大家——所以我决定进行一些测试,找出哪种方法实际上最快。我测试的五种方法是:
方法
这就是我所做的……
结果
我将首先展示结果,然后为感兴趣的人展示下面的代码。
正如预期的那样, ContainsKey 方法是最慢的,因此我将给出每个方法的速度与该方法的速度的比较。
结论
似乎只有 MutableInt 方法和 Trove 方法明显更快,因为只有它们提供了超过 10% 的性能提升。但是,如果线程是一个问题,AtomicLong 可能比其他的更有吸引力(我不太确定)。我还使用
final
变量运行了 TestForNull,但差异可以忽略不计。请注意,我没有分析不同场景中的内存使用情况。我很高兴听到任何人对 MutableInt 和 Trove 方法可能会如何影响内存使用有很好的见解。
就个人而言,我发现 MutableInt 方法最有吸引力,因为它不需要加载任何第三方类。所以除非我发现它有问题,否则这是我最有可能走的路。
编码
这是每个方法的关键代码。
包含密钥
测试为空
原子长
宝库
可变整数