我使用TreeMap
,其密钥为String
,值为List
个自定义对象。像这样:
Map<String, List<CustomObject>> map = new TreeMap<String, List<CustomObject>>();
我知道TreeMap上的insert和get操作具有O(log n)时间复杂度。但是,我并不完全清楚如何猜测处理TreeMap所需的时间,
有人可以帮助我找出用于查找
的方法将约40,000条记录放入TreeMap
所花费的时间(考虑到所有字符串都是随机且唯一的)。即,遵循40000次行:
map.put("SomeString", listOfCustomObjects)
一旦包含对get()
方法的调用,迭代密钥集所花费的时间:
for(String s: map.keySet()){
List<CustomObject> listOfCustomObjects =map.get(s);
//do something with the list
}
答案 0 :(得分:0)
编写测试并测量时间。没有可靠的方法来估计执行时间而没有实际执行。
确保基准密钥分发与实际密钥分发相匹配,因为平衡算法可能会严重影响执行时间。
答案 1 :(得分:0)
很难估计。这是一个小测试:
System.out.println("put\titeration");
for (int r = 0; r < 10; ++r) {
Map<String, List<Object>> map = new TreeMap<>();
List<Object> dummyList = new ArrayList<>();
long start, end, putTime, iterTime;
start = System.currentTimeMillis();
for (int i = 0; i < 1_000_000; ++i) {
map.put(String.valueOf(), dummyList);
}
end = System.currentTimeMillis();
putTime = (end - start);
start = System.currentTimeMillis();
for(String s: map.keySet()){
List<Object> listOfCustomObjects = map.get(s);
}
end = System.currentTimeMillis();
iterTime = (end - start);
System.out.println(putTime + "ms\t" + iterTime + "ms");
}
此测试将1.000.000个条目添加到TreeMap。这会重复十次。
为什么我使用1.000.000而不是40.000? 40.000几乎没有。我的结果大约是40ms到70ms。更多条目会导致结果之间的差异更大:
put iteration
1224ms 211ms
626ms 198ms
769ms 199ms
577ms 193ms
1179ms 194ms
438ms 190ms
445ms 201ms
309ms 200ms
378ms 198ms
396ms 205ms
我使用的是2.40 GHz CPU。
所以大部分时间需要~400ms,但有时需要两到三倍的时间。这是由于及时优化,内存管理或仅仅因为OS进程调度。怎么知道......
答案 2 :(得分:0)
微观标记是棘手而困难的。使用JMH,但请先阅读文档和一些教程,例如this one。
因此,对于1),只需使用JMH并查看需要多长时间。
关于2),做同样的事情:设计一个微基准测试,看看需要多长时间。但是,有一种更有效的方法来迭代地图的条目,即使用Map.entrySet
方法:
for (Entry<String>, List<CustomObjects>> e : map.entrySet()) {
String key = e.getKey();
List<CustomObjects> value = e.getValue();
// do something with the list
}
这种方式更好,因为在TreeMap
中,get
时间复杂度O(log n)
,因此调用get
n
次O(n log n)
,虽然使用entrySet
方法是常量(entrySet
返回一个集合,该集合是地图条目的视图),并且您已在每个条目中拥有该值。