如果并行处理,为什么在无限的数字流中按素数过滤会花费很长时间?

2024-01-12

我正在创建一个从 2 亿开始的无限整数流,使用朴素的素性测试实现来过滤该流以生成负载并将结果限制为 10。

Predicate<Integer> isPrime = new Predicate<Integer>() {
    @Override
    public boolean test(Integer n) {
        for (int i = 2; i < n; i++) {
            if (n % i == 0) return false;   
        }
        return true;
    }
};

Stream.iterate(200_000_000, n -> ++n)
    .filter(isPrime)
    .limit(10)
    .forEach(i -> System.out.print(i + " "));

这按预期工作。

现在,如果我在过滤之前添加对 parallel() 的调用,则不会生成任何内容,并且处理不会完成。

Stream.iterate(200_000_000, n -> ++n)
    .parallel()
    .filter(isPrime)
    .limit(10)
    .forEach(i -> System.out.print(i + " "));

有人能指出我这里发生的事情的正确方向吗?

编辑:我不是在寻找更好的素性测试实现(它旨在成为一个长期运行的实现),而是为了解释使用并行流的负面影响。


处理实际上已完成,但可能需要相当长的时间,具体取决于计算机上的硬件线程数。API文档 https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#limit-long-about limit 警告并行流可能会很慢。

实际上,并行流首先根据可用的并行级别将计算分成几个部分,对每个部分执行计算,然后将结果连接在一起。你的任务有多少部分?每个公共 FJP 线程一个 (=Runtime.getRuntime().availableProcessors()) 如果当前线程不在 FJP 中,则加(有时?) 1。您可以控制它添加

System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "4");

实际上,对于您的任务,您设置的数字越低,计算速度就越快。

无限任务如何拆分?您的特定任务由 Iterator Spliterator 处理trySplit http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/Spliterators.java#Spliterators.IteratorSpliterator.trySplit%28%29方法创建从 1024 开始不断增加大小的块。您可以自己尝试:

Spliterator<Integer> spliterator = Stream.iterate(200_000_000, n -> ++n).spliterator();
Spliterator[] spliterators = new Spliterator[10];
for(int i=0; i<spliterators.length; i++) {
    spliterators[i] = spliterator.trySplit();
}
for(int i=0; i<spliterators.length; i++) {
    System.out.print((i+1)+": ");
    spliterators[i].tryAdvance(System.out::println);
}       

因此,第一个块处理范围 200000000-200001023 的数字,第二个块处理范围 200001024-200003071 的数字,依此类推。如果您只有 1 个硬件线程,您的任务将被拆分为两个块,因此将检查 3072。如果你有 8 个硬件线程,你的任务将被分成 9 个块,并且将检查 46080 个数字。只有在处理完所有块之后,并行计算才会停止。将任务分割成如此大的块的启发式方法在您的情况下效果不佳,但如果该区域周围的素数在几千个数字中出现一次,您会看到性能提升。

也许您的特定场景可以在内部进行优化(即,如果第一个线程发现已经达到限制条件,则停止计算)。请随时向 Java 错误跟踪器报告错误。


Update在深入挖掘 Stream API 内部之后,我得出结论,当前的行为是一个错误,提出了一个问题 https://bugs.openjdk.java.net/browse/JDK-8148250并发布了一个patch http://cr.openjdk.java.net/~tvaleev/webrev/8148250/r1/。该补丁很可能会被 JDK9 接受,甚至可能向后移植到 JDK 8u 分支。使用我的补丁,并行版本仍然没有提高性能,但至少它的工作时间与顺序流工作时间相当。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果并行处理,为什么在无限的数字流中按素数过滤会花费很长时间? 的相关文章

随机推荐

  • 带有 Docker 执行器 /usr/bin/bash 的 Gitlab-CI:第 90 行:git:找不到命令

    我有一个本地 GitLab 服务器和带有 Docker 执行器的 gitlab ci 运行程序 我想使用 gitlab ci 构建 第一阶段 我的 Maven 项目 由于我使用 buildnumber maven plugin 我向 git
  • 为什么看似空的文件和字符串会产生 md5sum?

    考虑以下 md5sum dev null d41d8cd98f00b204e9800998ecf8427e dev null touch empty md5sum empty d41d8cd98f00b204e9800998ecf8427e
  • 为什么在新的 virtualenv 中导入 numpy 需要 5 秒?

    背景 你好 我们编写的 Python 代码在我们无法控制的服务器上运行 我们不太了解代码运行的环境 如果我们的代码运行时间超过 3 秒 就会被拒绝 因此 我决定开始使用虚拟环境对我们的代码进行计时 以给出最坏情况下的运行时间估计 Quest
  • Java swing:选择/取消选择 JButton 以模仿脉冲

    FE我有一个电子邮件客户端 它接收新消息 带有传入消息的按钮开始执行某些操作 直到用户单击它以查看发生了什么 我试图通过选择 等待然后取消选择按钮来吸引注意力 但这没有任何作用 do button setSelected true Thre
  • 乳胶输出

    当我编译乳胶文件时 它还会生成 txt bbl aux 文件 它们没有用 因为我可以删除它们而不会造成任何损害 我的问题是这些文件的用途是什么以及如何在编译 tex 文件时选择不生成它们 这些文件很有用 代表多遍排版过程的输出 如果删除它们
  • Python numpy 数组元素不改变值

    所以我的 python 代码中遇到了一个问题 我将其归结为 假设我们有一个函数u def u y t h float 10 U0 float 1 return U0 h y 和一个数组 a np array 0 2 2 然后执行以下操作 a
  • 使用 Laravel Mix 时如何包含 webpack 插件?

    如果我使用 WebPack 和 Laravel Mix 我应该如何包含 webpack 插件 我很困惑将插件代码添加到哪个文件中 我的以下尝试似乎没有运行我的插件 该插件应该压缩 js css 文件 但事实并非如此 webpack conf
  • 使用 Sympy 集成到 Python 中

    我目前正在使用Sympy帮助我进行数学计算 现在 我正在尝试执行数值积分 但每次运行脚本时都会出现错误 这是脚本 from sympy import cst qe 1 60217646 10 19 m0 N 1 25663706 10 6
  • 无论如何,我可以在谷歌合作实验室下载该文件吗?

    我正在这个 Codelab 的 Google Colaboratory 中尝试张量流 我需要下载 http download tensorflow org example images flower photos tgz http down
  • PHP 复选框多重删除

    我的实现似乎不起作用 您能指出可能出现的问题或指出更好的解决方案吗 当我选中复选框并单击删除按钮时 它似乎没有执行任何操作 请帮助我 div class page img class page src images DISCLAIMER p
  • 获取当月数据记录条数

    我正在尝试查找数据库中当月结束的车辆记录总数 我不知道我应该在里面写什么InvoiceDate本例中的部分 public void MonthlyStatus NetContext context var monthlyStatus fro
  • Zend Framework,将 URL 的扩展名映射到格式参数?

    是否可以将 URL 的扩展名映射到 ZF 中的格式参数 我希望默认路由仍然有效 包括从 URI 映射参数 因此您可以说 http example com controller action param1 value1 param2 valu
  • 何时返回 IOrderedEnumerable?

    Should IOrderedEnumerable纯粹用作语义值的返回类型 例如 当在表示层中消费模型时 我们如何知道集合是否需要排序或已经排序 如果存储库用一个存储过程包装了一个存储过程 该怎么办 ORDER BY条款 存储库是否应该返回
  • 不存在类型变量 U 的实例,因此 void 符合 U

    我正在努力避免isPresent检查下面的代码 但编译器发出错误消息 没有类型变量的实例U存在使得void符合U 打电话给printAndThrowException 这是我的代码 values stream filter value gt
  • 您在 ASP.NET MVC 中使用什么视图引擎? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我知道您可以在 ASP NET MVC 中使用几种不同的视图引擎 ASPX 显然 NV速度 Brail NHaml et al 默认的 ASPX
  • 更改“查看购物车”按钮的文本

    我正在使用 woocommerce 插件 但我遇到了如何更改查看购物车按钮文本的问题 希望有人可以帮助解决我的问题 这是my site http unlieusurterre fix it buddy clients com the tru
  • 无服务器 python 请求具有长时间超时?

    我有几个遵循类似格式的 python 脚本 您传入一个日期 它要么 检查我的 S3 存储桶中文件名中包含该日期的文件 并解析它 或者 运行一个 python 脚本 对文件进行一些分析该日期的文件 运行时间超过 1 小时 我正在寻找一种无服务
  • PHP MySQL 数据库连接

    执行查询 和其他数据库操作 后是否有必要显式关闭数据库连接 不 php 自动执行此操作 不过 您可以将其称为 良好的编程实践 来清理 也称为关闭连接
  • Apache Spark + Parquet 不遵守使用“分区”暂存 S3A 提交器的配置

    我正在使用本地计算机上的 Apache Spark 3 0 将分区数据 Parquet 文件 写入 AWS S3 而无需在计算机中安装 Hadoop 当我有很多文件要写入大约 50 个分区 partitionBy date 时 我在写入 S
  • 如果并行处理,为什么在无限的数字流中按素数过滤会花费很长时间?

    我正在创建一个从 2 亿开始的无限整数流 使用朴素的素性测试实现来过滤该流以生成负载并将结果限制为 10 Predicate