个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈
我希望这个问题对于本论坛来说不是太基本了,但是我们会看到的。 我想知道如何重构一些代码以获得更好的性能,而这些性能已经运行了很多次。
假设我正在使用地图(可能是HashMap)创建一个单词频率列表,其中每个键是一个带有要计算单词的String,并且值是一个Integer,每次找到该单词的标记时都会增加。
在Perl中,增加这样的值非常容易:
$map{$word}++;
但是在Java中,它要复杂得多。 这是我目前的操作方式:
int count = map.containsKey(word) ? map.get(word) : 0;
map.put(word, count + 1);
当然,哪个依赖于较新的Java版本中的自动装箱功能。 我想知道您是否可以建议一种更有效的递增此值的方法。 避开Collections框架并改用其他东西,甚至有良好的性能原因吗?
更新:我已经测试了几个答案。 见下文。
#1楼
一些测试结果
对于这个问题,我已经得到了很多很好的答案-谢谢大家-因此,我决定进行一些测试,找出哪种方法实际上最快。 我测试的五种方法是:
- 我在问题中介绍的“ ContainsKey”方法
- Aleksandar Dimitrov建议的“ TestForNull”方法
- Hank Gay建议的“ AtomicLong”方法
- jrudolph建议的“激励”方法
- phax.myopenid.com建议的“ MutableInt”方法
方法
这是我做的...
- 创建了五个相同的类,除了以下所示的差异。 每个班级都必须执行我所介绍的场景的典型操作:打开一个10MB的文件并读入它,然后对文件中所有单词标记的频率进行计数。 由于平均只需要3秒钟,因此我让它执行了10次频率计数(而不是I / O)。
- 定时10次迭代的循环而不是I / O操作的时间,并基本上使用Java Cookbook中的Ian Darwin的方法记录所花费的总时间(以时钟秒为单位)。
- 依次执行了所有五个测试,然后又进行了三次。
- 平均每种方法的四个结果。
结果
我将首先提供结果,并为感兴趣的人提供以下代码。
如所预期的, ContainsKey方法是最慢的,因此,与该方法的速度相比,我将给出每种方法的速度。
- ContainsKey: 30.65