我在网上遇到了一个算法http://www.coderanch.com/t/201836/Performance/java/Hashtable-vs-Hashmap 并决定测试它
public class MapTest{
static int sizeOfTrial = 100000;
static String[] keys = new String[sizeOfTrial];
static String[] vals = new String[sizeOfTrial];
public static void main(String[] args) {
//init sizeOfTrial key/value pairs
for (int i=0; i < sizeOfTrial; i++){
String s1 = "key"+ i;
String s2 = "val"+ i;
keys[i] = s1;
vals[i] = s2;
}
test(new TreeMap(), "TreeMap");
test(new Hashtable(), "Hashtable");
test(new HashMap(), "HashMap");
test(new Hashtable(200000), "Hashtable presized");
test(new HashMap(200000), "HashMap presized");
}
public static void test(Map tm, String name){
long t1 = System.currentTimeMillis();
for (int i=0; i < sizeOfTrial; i++){
tm.put(keys[i],vals[i]);
}
for (int i=0; i < sizeOfTrial; i++){
tm.get(keys[i]);
}
long t2 = System.currentTimeMillis();
System.out.println("total time for " + name + ": " + (t2-t1));
}
}
我得到了以下结果
total time for TreeMap: 1744
total time for Hashtable: 446
total time for HashMap: 234
total time for Hashtable presized: 209
total time for HashMap presized: 196
这个JVM是依赖的还是任意的,还是真的提供了更快的访问和存储时间?
答案 0 :(得分:11)
预定义任何容器类型的预期大小将提供更快的存储时间,因为存储不必经常在运行时动态重新分配。通常,后备存储是某种阵列,当超出可用容量时,必须将阵列复制到新的更大阵列中。如果您将大量对象存储到容量非常小的容器中,这可能需要多次执行,这是一项昂贵的操作。
从地图上阅读的表现不应受到任何影响。您可以通过将tm.put
部分与tm.get
部分分开计时来更好地证明这一点。
修改:为了进一步说明这一点,我将代码与tm.put
分开修改为时间tm.get
。以下是我机器上的结果:
total time for TreeMap tm.put: 159
total time for TreeMap tm.get: 74
total time for Hashtable tm.put: 20
total time for Hashtable tm.get: 10
total time for HashMap tm.put: 42
total time for HashMap tm.get: 5
total time for Hashtable presized tm.put: 11
total time for Hashtable presized tm.get: 9
total time for HashMap presized tm.put: 6
total time for HashMap presized tm.get: 4
请注意,Hashtable
常规和tm.put
之间的差异是〜2的因子。 SImilarly,HashMap
,常规和预设之间的差异是存储的约7倍。但是,从阅读方面来看,Hashtable
和Hashmap
在两种情况下tm.get
的时间安排大致相同(10 ms
与9 ms
{{1}对Hashtable
而言,5 ms
与4 ms
对HashMap
}。另请注意,在推定的情况下,推杆和获得的时间大致相同,总时间大致相同。