Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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 为什么map.values().stream()比Array.stream(Array)慢得多_Java_Arrays_Hashmap - Fatal编程技术网

Java 为什么map.values().stream()比Array.stream(Array)慢得多

Java 为什么map.values().stream()比Array.stream(Array)慢得多,java,arrays,hashmap,Java,Arrays,Hashmap,为大学第二学期计算机科学创建两个结构,计算文本中的单词。 一个实现使用一个包含单词对象的数组,该数组将单词保存为字符串,并将其频率保存为int。 另一个使用as HashMap,单词作为键,频率作为值。 现在,它们是一个函数“totalWords”,它应该返回所有频率的总和 在HashMap变量中: return _map.values().stream().reduce(0, (a, b) -> a + b); 在阵列变量中: return Arrays.stream(_words)

为大学第二学期计算机科学创建两个结构,计算文本中的单词。 一个实现使用一个包含单词对象的数组,该数组将单词保存为字符串,并将其频率保存为int。 另一个使用as HashMap,单词作为键,频率作为值。 现在,它们是一个函数“totalWords”,它应该返回所有频率的总和

在HashMap变量中:

return _map.values().stream().reduce(0, (a, b) -> a + b);
在阵列变量中:

return Arrays.stream(_words)
            .map((word) -> word != null ? word.count() : 0)
            .reduce(0, (a, b) -> a + b);
我的问题是:在一个测试文本非常短的JUnit测试中,数组变量需要大约0.001s,map变量需要0.040s,我不明白map为什么需要这么多时间。
有人有解释或者更好的解决方案吗?

原因之一是迭代
HashMap
可能比
数组
慢得多,原因是
局部性
。现代处理器的计算瓶颈主要是内存访问,这就是为什么要使用
cache
<代码>数组将数据存储在连续的内存块中,这意味着当您将该内存块交换到缓存中时,很可能您正在使用缓存中的所有内容,或者您得到
缓存命中数
,因此缓存类似于连续的数据内存。另一方面,
HashMap
的每个元素都存储在内存中的不同位置,因此当您遍历
HashMap
时,会出现大量的缓存
未命中
,最终会一直在缓存中交换数据,这大大降低了程序的速度


虽然
HashMap
的实际实现是以优化的方式进行的,以便内存中的数据聚集在一起,但即使在这种情况下,(@Radiodef)由于
HashMap
使用某种
链表
,因此
HashMap
的每个元素都包含额外的指针,因此
HashMap
数组
消耗更多内存,更多内存意味着更多的
缓存未命中
和更多的
页面错误
,因此
HashMap
通常比
数组

HashMap是一种数据结构,它(基本上)具有一个链表数组:

0: [ a ] -> [ b ] -> [ c ]
1: [   ]
2: [   ]
3: [ d ] -> [ e ]
4: [   ]
5: [ f ]
6: [   ]
7: [   ]
链表是键具有相同哈希代码的位置(称为“冲突”)

因此,数据结构中有“漏洞”,而且它比数组更零碎,因为HashMap的每个条目都有一个对象。迭代HashMap将从内存中产生比迭代数组更多的负载


我也同意你的观点,因为你的基准可能有缺陷。一个好的基准测试可能仍然会显示阵列的性能更好,但没有那么明显的区别。

主要原因是你的基准测试有缺陷。在Java中编写这样一个微型基准测试是极其困难的。第二个原因是迭代HashMap的条目不能像迭代数组那样快。关于“更好的解决方案”的旁注:迭代
LinkedHashMap
的元素往往明显快于普通的
HashMap
。但速度不如数组快。。。