繁体   English   中英

使用谓词通过parallelStream筛选并发映射或列表是否更快?

[英]Is it faster to use Predicates to filter a Concurrent Map or a List, using parallelStream?

我在List<FileMap>存储了多个FileMap对象,目前大约有500,000个对象。

我正在使用谓词使用parallelStream过滤列表。 我现在正在阅读文档,看到有一个名为Collectors.toConcurrentMap()的函数。 我对ConcurrentHashMap很熟悉,并且知道它更快,因为有多个线程可以划分地图。

将简单的ArrayList更改为toConcurrentMap ,然后将谓词与parallelStream一起使用会更快吗? 当前,如果我在该List上使用parallelStream并使用serialStream,则它的运行速度相同。

Map是key-value对的集合,其中键是唯一的。 您拥有的数据不是地图,而是列表。 有很多问题:

  1. 尝试将列表转换为映射将需要提供键和值映射功能。
  2. 您最终将获得比原始结构更大的结构。
  3. 您将必须确保键映射函数返回唯一值,从而使并行化成为不可能(可以使用同步,但这会大大降低性能)。
  4. 映射的结构比列表(实际上是数组)要复杂得多,并且构造它要花费更多的时间。
  5. ConcurrentMap具有额外的复杂性以确保线程安全-尽管它以比仅使所有方法都同步的更智能的方式完成,但它仍然会影响性能。
  6. 在地图上进行迭代与数据的存储方式没有多大关系-无论如何,您都需要获取一个设置值。

过滤列表中的元素可以进行大量(且很容易)并行化。 具有n核,其中n是列表的长度,您可以实现与log(n)一样好的性能-这当然是使用专用的并行算法并使用图形卡而不是CPU,因为它们虽然功能不那么强大,但具有数千个核心。

我对一个具有1亿个整数的列表进行了一些测试,并使用并行流(大约350ms(我猜Java仅使用2个线程))依次处理了约700ms(尝试将列表转换为ConcurrentMap已耗尽内存)几分钟后出现错误。

您已经提到使用stream()parallelStream()不会改变性能。 我建议调查一下Java如何选择在并行流中使用多少个线程(以及如何更改)。 这也受到资源的影响-运行CPU消耗的线程多于CPU内核数会由于上下文切换而降低性能。 我建议只使用与您拥有的内核数量一样多的线程,或者减少一个线程-以便一个内核可以用于所有其他OS工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM