加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

并行Scala的迭代器

发布时间:2020-12-16 09:21:28 所属栏目:安全 来源:网络整理
导读:请注意:这不是一个重复的问题,因为这个问题指定了迭代器所有的所有方法,而不仅仅是map和flatMap.所以Future.traverse不是一个很好的答案. 假设我有这个简单的说法: (1 to 100).toSet.subsets.find(f) 它工作完美.它是懒惰的,一旦找到一个元素,就不会使用大
请注意:这不是一个重复的问题,因为这个问题指定了迭代器所有的所有方法,而不仅仅是map和flatMap.所以Future.traverse不是一个很好的答案.

假设我有这个简单的说法:

(1 to 100).toSet.subsets.find(f)

它工作完美.它是懒惰的,一旦找到一个元素,就不会使用大量的内存并返回.当您要并行化时,会出现此问题.你可能会说,这是Scala,必须有.par或迭代器,但是没有.

在互联网上提出的解决方案是使用.grouped,但它不如我想要的那么好.为什么?

val it = (1 to 100).toSet.subsets.grouped(1000000).map(_.par.find(f)).flatten
if (it.hasNext) Some(it.next) else None

>使用更多的内存我知道它仍然是O(1),但让我们在这里完美:)
>这不是完全可以并行化(按照Amdahl定律).当.grouped正在为下一个百万个元素块使用迭代器时,除了一个线程之外的所有等待.如果迭代器消耗昂贵,这是特别有问题的.此外,必须有一个开销,产生一组新的线程来处理新的块.
>生成更复杂/更长的代码(参见示例).如果迭代器有.nextOption,那么它会缩短代码.

有没有其他的,尽管编程我自己的生产者 – 消费者模型(迭代器是生产者,线程是消费者),然后最终减少步骤?

解决方法

你可以使用.toStream.这将产生一个将记录值的延迟流.它有.par.

它将在堆上分配一些包装器,但是如果您小心(不要围绕流的指针),则只会导致GC压力,但不会增加剩余内存占用.它仍然会很快.请注意,并行集合会引起很多开销,如果您的每个元素的计算不够昂贵,可能不值得.

迭代器只是太低级别才能并行化.但是实际上并不需要并行迭代器,而是迭代器的并行遍历,您可以从标准库中获得Future.traverse.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读