TreeMap需要多长时间?

时间:2017-05-26 07:33:06

标签: java performance collections time-complexity treemap

我使用TreeMap,其密钥为String,值为List个自定义对象。像这样:

Map<String, List<CustomObject>> map = new TreeMap<String, List<CustomObject>>();

我知道TreeMap上的insert和get操作具有O(log n)时间复杂度。但是,我并不完全清楚如何猜测处理TreeMap所需的时间,

有人可以帮助我找出用于查找

的方法
  1. 将约40,000条记录放入TreeMap所花费的时间(考虑到所有字符串都是随机且唯一的)。即,遵循40000次行:

    map.put("SomeString", listOfCustomObjects)
    
  2. 一旦包含对get()方法的调用,迭代密钥集所花费的时间:

    for(String s: map.keySet()){
        List<CustomObject> listOfCustomObjects =map.get(s);
        //do something with the list
    }
    

3 个答案:

答案 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 nO(n log n) ,虽然使用entrySet方法是常量(entrySet返回一个集合,该集合是地图条目的视图),并且您已在每个条目中拥有该值。

相关问题