Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hashMap.get(“字符串键”)的速度是否会受到hashMap大小的影响?_Java_Hashmap - Fatal编程技术网

Java hashMap.get(“字符串键”)的速度是否会受到hashMap大小的影响?

Java hashMap.get(“字符串键”)的速度是否会受到hashMap大小的影响?,java,hashmap,Java,Hashmap,我提出了一个非常大胆的想法。也就是说,我想使用HashMap而不是数据库来存储聊天应用程序的数据 因此,当用户发送聊天信息时,该特定用户的聊天信息将使用storeMsg()存储到HashMap中 每个用户都有一个单独的聊天室。每5秒钟,该特定用户的聊天室将发送一个getMsg()方法来检索该聊天室中的最新消息。在检索到消息后,它将删除与该特定用户的聊天室相关的所有消息,这样我们就可以避免开销 因此,只有存在于聊天室中的用户才能看到消息,消息可以一个接一个地追加。最近进入聊天室的新用户将无法看到以

我提出了一个非常大胆的想法。也就是说,我想使用
HashMap
而不是数据库来存储聊天应用程序的数据

因此,当用户发送聊天信息时,该特定用户的聊天信息将使用
storeMsg()
存储到
HashMap

每个用户都有一个单独的聊天室。每5秒钟,该特定用户的聊天室将发送一个
getMsg()
方法来检索该聊天室中的最新消息。在检索到消息后,它将删除与该特定用户的聊天室相关的所有消息,这样我们就可以避免开销

因此,只有存在于聊天室中的用户才能看到消息,消息可以一个接一个地追加。最近进入聊天室的新用户将无法看到以前的消息。这类似于点对点聊天

每个用户都有一个唯一的字符串用户名,如“tomhan12”、“Mary2”、“123cat”等

所以,我的问题是,如果
hMap
Key
s是
String
s&如果
hMap
有数百万个条目,那么
hMap.get(str)
的速度会受到影响吗

我们能否将
字符串用户名
转换为唯一的整数,然后“
hMap.put(thauniqueintegernumber,message)
”以获得更高的性能?或者HashMap为我们做到了这一点,所以我们不需要这样做?

HashMap
get()
方法提供了O(1)时间复杂性,如果key
hashCode()
函数具有良好的分布(对于字符串是如此)。地图的大小不会影响操作性能(从技术上讲,当地图变大时,碰撞会更频繁,但这是另一回事)


字符串
键替换为
整数
键不会显著提高性能。

HashMap
get
具有预期的恒定运行时间,这意味着其运行时间不应取决于
HashMap
的大小。当然,这依赖于密钥的
hashCode
方法的良好实现,但是您的密钥是
String
,所以这应该不是问题


这就是说,使用大型的
HashMap
(或任何其他大型数据结构)会消耗大量内存,因此您应该注意,您没有遇到内存不足的问题,这会降低应用程序的速度。

理论上
HashMap#get(…)
有O(1)保证,如果地图上没有人口过多,物品在桶中正确分配。实际上,这取决于实现,但如果人口过多,地图通常会慢一点。通常,
HashMap
的负载系数应低于0.7,以避免人口过多并保持最佳性能。尽管速度会很小(除了一些极端情况)。

根据javadoc:

这个实现为基本操作(get和put)提供了恒定的时间性能,假设哈希函数将元素正确地分散在存储桶中。对集合视图的迭代需要与HashMap实例的“容量”(bucket数)加上其大小(键值映射数)成比例的时间。因此,如果迭代性能很重要,那么不要将初始容量设置得太高(或负载系数太低),这一点非常重要

HashMap实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的存储桶数,初始容量只是创建哈希表时的容量。负载因子是在自动增加哈希表容量之前允许哈希表达到的满度的度量。当哈希表中的条目数超过加载因子和当前容量的乘积时,哈希表将被重新格式化(即,重建内部数据结构),以便哈希表的存储桶数大约是存储桶数的两倍

作为一般规则,默认负载系数(.75)在时间和空间成本之间提供了良好的折衷。较高的值会减少空间开销,但会增加查找成本(反映在HashMap类的大多数操作中,包括get和put)。在设置初始容量时,应考虑map中的预期条目数及其负载系数,以尽量减少再灰化操作次数。如果初始容量大于最大入口数除以负载系数,则不会发生再灰化操作

由于HashMap将其值存储在散列存储桶中,因此根据映射散列的散列冲突量,查找通常可以在O(1)和O(N)之间进行

让我们测试此性能: 为了测试映射的性能,我们将运行一个测试,首先将100/100000项插入映射,然后在循环中调用映射上的get(“0-9”),以测试查找的性能。我们使用以下代码来执行此操作:

import java.util.HashMap;
public class HashMapTest {
    public static void test(int items, boolean print) {
        System.gc();
        System.gc();
        HashMap<String,Object> map = new HashMap<>();
        for(int i = 0; i < items; i++) {
            map.put("" + i, map);
        }
        long start = System.nanoTime();
        for(int i = 0; i < 100000; i++) {
            map.get("0");
            map.get("1");
            map.get("2");
            map.get("3");
            map.get("4");
            map.get("5");
            map.get("6");
            map.get("7");
            map.get("8");
            map.get("9");
        }
        long end = System.nanoTime();
        long time = end - start;
        if(print) {
            System.out.println("items: "+ items + " time: "+ time);
        }
    }
    
    public static void main(String ... args) {
        // warmup
        for(int i = 0; i < 2; i++) {
            test(100, false);
        }
        for(int i = 0; i < 2; i++) {
            test(1000000, false);
        }
        // Real test:
        for(int i = 0; i < 10; i++) {
            test(100, true);
        }
        for(int i = 0; i < 10; i++) {
            test(1000000, true);
        }
    }
}

如果我们分析测试结果,我们看不到访问时间的“真正”改善,因为我们还有1000个项目。

我们可以将字符串用户名转换为唯一的整数,然后“hMap.put(thauniqueintegernumber,message)”以获得更高的性能吗?或者HashMap为我们做到了这一点,所以我们不需要这样做?
这是HashMap存储密钥、值pairFYI的工作方式的一部分:5秒可能是获取消息的非常长的时间跨度,因为有些用户在发送消息之前只写几个字符,比如:hi,然后在2次峰会中,我们插入信息,几秒钟后,我们删除该信息,我们可以最小化内存problem@Tum你提到有数百万的条目。如果这些条目足够大,则需要一个小条目
import java.util.HashMap;
public class HashMapTest {
    public static void test(int items, boolean print) {
        System.gc();
        System.gc();
        HashMap<String,Object> map = new HashMap<>();
        for(int i = 0; i < items; i++) {
            map.put("" + i, map);
        }
        long start = System.nanoTime();
        for(int i = 0; i < 100000; i++) {
            map.get("0");
            map.get("1");
            map.get("2");
            map.get("3");
            map.get("4");
            map.get("5");
            map.get("6");
            map.get("7");
            map.get("8");
            map.get("9");
        }
        long end = System.nanoTime();
        long time = end - start;
        if(print) {
            System.out.println("items: "+ items + " time: "+ time);
        }
    }
    
    public static void main(String ... args) {
        // warmup
        for(int i = 0; i < 2; i++) {
            test(100, false);
        }
        for(int i = 0; i < 2; i++) {
            test(1000000, false);
        }
        // Real test:
        for(int i = 0; i < 10; i++) {
            test(100, true);
        }
        for(int i = 0; i < 10; i++) {
            test(1000000, true);
        }
    }
}
items: 100     time: 11102830
items: 100     time: 12228567
items: 100     time: 34309933
items: 100     time: 36976824
items: 100     time: 34290557
items: 100     time: 19819022
items: 100     time: 14747533
items: 100     time: 15818922
items: 100     time: 15026368
items: 100     time: 16830762
items: 1000000 time: 12421862
items: 1000000 time: 13931351
items: 1000000 time: 13083504
items: 1000000 time: 11453028
items: 1000000 time: 13265455
items: 1000000 time: 11030050
items: 1000000 time: 11362288
items: 1000000 time: 11521082
items: 1000000 time: 11198296
items: 1000000 time: 11303685

items 100     min: 11102830
items 100     max: 36976824
items 1000000 min: 11030050
items 1000000 max: 13931351