【发布时间】:2017-05-06 14:10:25
【问题描述】:
我需要迭代一个HashMap,其中包含10^5 轮次的整数。我随机生成整数。然后,我对该整数执行所需的算术运算。之后,我正在检查 HashMap 是否包含此 Integer => 如果它包含此整数,我会递增该整数并重新检查 HashMap 是否包含新整数,直到该整数不存在于 HashMap 中。如果它不包含整数,我将整数添加到 HashMap。
我在下面添加了我的代码。 'start' 和 'end' cmets 之间的代码耗时太长。
如果我在“开始”和“结束”之间comment 这段代码,它会在不到一秒的时间内执行。
所以,Random.nextInt() 或HashMap.containsKey() 中没有消耗时间
MyProgram.java
import java.util.HashMap;
import java.util.Random;
public class MyProgram {
public static void main(String[] args) {
long total = 0;
int randomInt;
int count = 100000;
int divider = 3;
Random random = new Random();
HashMap<Integer, Integer> map = new HashMap<>();
for(int i=0; i < count; i++){
randomInt = random.nextInt(count);
// start
int value1 = randomInt / divider;
int value2 = (randomInt % divider != 0) ? 1 : 0;
randomInt = value1 + value2;
// end
while(map.containsKey(randomInt)){
randomInt++;
}
map.put(randomInt, 0); // don't care about value
total += randomInt;
}
System.out.println("Total : " + total);
}
}
此实现需要 30 多秒。
我可以使用 List、Arrays、ArrayLists 等。如果您认为它们很快的话。请举例说明。
【问题讨论】:
-
您不需要检查地图是否已经包含键,因为您不关心值。您可以尝试继续推送随机键,直到您的地图中有
count键。不确定这会更快,但试一试 -
需要时间的可能是整数的装箱。也许您应该创建一个可变整数类型并使用它。此外,您可以使用
randomInt = (random.nextInt(count) + divider - 1) / divider而不是您的value1和value2计算 -
我的意思是,如果您的键 (randomInt) 是 17,并且它已经存在于地图中,并且如果您再次将 17 放入地图中,那么地图将替换针对 17 保存的任何值,并且用新值替换它。您为所有键保持相同的值 0。另外,我刚刚运行了您的代码,并观察到 while 循环一直在占用。我把它注释掉了,程序在 ~ 2 秒内运行
-
对你的性能损失的解释是你执行
containsKey的次数,当数字重复时会更大,在执行那个算术时会更大。 -
@rupinderjeet 谢谢,但这是一种低劣的方法,您应该改用 BitSet。这就是我删除它的原因
标签: java performance time hashmap