java HashMap初始化容量的效率问题
阿神
阿神 2017-04-17 17:20:39
[Java讨论组]

问题描述

在本机测试用例中,初始化键值对100W,初始化容量200W(其实当键值对更少,比如10W,5W等级别,情况也是类似的),发现初始化容量的效率和不初始化容量的效率并不是稳定不变的,为何一直听说当可预估map内容大小时,应该预填容量值呢?

测试代码

int puts = 1000000, cap = puts * 2;
for (int k = 0; k < 5; k++) {
    System.out.println("=========独立测试开始==========");
    HashMap<Integer, Integer> map5 = new HashMap<Integer, Integer>(cap);
    long time01Start = System.currentTimeMillis();
    for (int i = 0; i < puts; i++) {
        map5.put(i, i);
    }

    System.out.println("HashMap初始化容量" + puts / 10000 + "W的耗时:" + (System.currentTimeMillis() - time01Start) + "ms");

    HashMap<Integer, Integer> map6 = new HashMap<Integer, Integer>();
    long time02Start = System.currentTimeMillis();
    for (int i = 0; i < puts; i++) {
        map6.put(i, i);
    }

    System.out.println("HashMap未初始化容量" + puts / 10000 + "W的耗时:" + (System.currentTimeMillis() - time02Start) + "ms");
    System.out.println("=========独立测试结束==========");
}

5次的测试结果

=========独立测试开始==========
HashMap初始化容量100W的耗时:964ms
HashMap未初始化容量100W的耗时:603ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:119ms
HashMap未初始化容量100W的耗时:658ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:26ms
HashMap未初始化容量100W的耗时:72ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:154ms
HashMap未初始化容量100W的耗时:34ms
=========独立测试结束==========
=========独立测试开始==========
HashMap初始化容量100W的耗时:134ms
HashMap未初始化容量100W的耗时:34ms
=========独立测试结束==========
阿神
阿神

闭关修行中......

全部回复(3)
高洛峰

你运行时的JVM堆多大?

黄舟

初始化不是应该用

     public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);

        this.loadFactor = loadFactor;
        threshold = initialCapacity;
        init();
    }
PHP中文网

测试方法不太科学。

  1. 最好分开独立测试,放在循环里也不是不行,只是有时候结果不太准确,每次循环之间可能会有影响

  2. 考虑JVM内存大小对结果可能产生的影响

  3. 应该测试两种情况:预分配容量和不预分配容量的先后顺序可能会对结果有影响,哪个先哪个后应该各占测试次数的一半(个人感觉题主的结果应该主要是受到了这一条的影响

  4. 测试数据应该再随机一点,而不是用一个循环然后不断i++。最好能够使用随机字符串或其他对象进行测试(为避免创建对象的影响,可以预先生成所有数据)

  5. 考虑loadFactor的设置

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号