为什么这个主要测试这么慢?

2023-11-27

这段代码取自《Haskell Road to Logic, Math andProgramming》一书。它实现了埃拉托斯特尼筛法并解决了欧拉计划问题 10。

sieve :: [Integer] -> [Integer]
sieve (0 : xs) = sieve xs
sieve (n : xs) = n : sieve (mark xs 1 n)
  where
    mark :: [Integer] -> Integer -> Integer -> [Integer]
    mark (y:ys) k m | k == m = 0 : (mark ys 1 m)
                    | otherwise = y : (mark ys (k+1) m)

primes :: [Integer]
primes = sieve [2..]

-- Project Euler #10
main = print $ sum $ takeWhile (< 2000000) primes

实际上它的运行速度甚至比朴素的素数测试还要慢。 有人可以解释这种行为吗?

我怀疑这与迭代标记函数中列表中的每个元素有关。

Thanks.


您正在使用此算法构建二次数量的未评估重击。该算法严重依赖惰性,这也是它无法扩展的原因。

让我们来看看它是如何工作的,希望这能让问题变得显而易见。为了简单起见,假设我们想要print的元素primes无穷无尽,即我们想要一个接一个地评估列表中的每个单元格。primes定义为:

primes :: [Integer]
primes = sieve [2..]

由于 2 不为 0,因此第二个定义sieve适用,并且 2 被添加到素数列表中,列表的其余部分是一个未评估的重击(我使用tail而不是模式匹配n : xs in sieve for xs, so tail实际上并没有被调用,并且不会在下面的代码中添加任何开销;mark实际上是唯一的 thunked 函数):

primes = 2 : sieve (mark (tail [2..]) 1 2)

现在我们想要第二个primes元素。因此,我们浏览一下代码(供读者练习)并最终得到:

primes = 2 : 3 : sieve (mark (tail (mark (tail [2..]) 1 2)) 1 3)

再次相同的过程,我们要评估下一个素数......

primes = 2 : 3 : 5 : sieve (mark (tail (tail (mark (tail (mark (tail [2..]) 1 2)) 1 3))) 1 5)

这开始看起来像 LISP,但我离题了……开始看到问题了吗?对于中的每个元素primes列表,一个越来越大的堆栈mark必须对应用程序进行评估。换句话说,对于列表中的每个元素,必须通过评估每个元素来检查该元素是否被任何前面的素数标记。mark堆栈中的应用程序。因此对于n~=2000000,Haskell 运行时必须调用函数,从而产生深度约为 ... 我不知道,137900 (let n = 2e6 in n / log n给出下限)?类似的事情。这可能是导致速度变慢的原因;或许vacuum可以告诉你更多(我现在没有一台同时带有 Haskell 和 GUI 的计算机)。

埃拉托斯特尼筛法在 C 等语言中起作用的原因是:

  1. 您没有使用无限列表。
  2. 由于 (1),您可以在继续下一个之前标记整个数组n,根本没有调用堆栈开销。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么这个主要测试这么慢? 的相关文章

  • 如何更换HXT中的节点?

    给定一个示例 xml 文件
  • 关于“没有绑定的类型签名”的错误

    我在 Haskell 中遇到 ASCII 问题 fromEnum Char gt Int toEnum Int gt Char offset Int offset fromEnum A fromEnum a toUpper Char gt
  • RankN多态性和令人发指的克莱斯利之箭

    我不明白为什么 demobind1 的定义会产生一些编译器错误 它看起来像一个愚蠢的翻转 但不知何故 LANGUAGE GADTs LANGUAGE RankNTypes ScopedTypeVariables TypeOperators
  • 使用带有两个列表而不是一个列表的地图。可以筑巢吗?

    我需要多次运行一个带有两个参数的函数 我有两个包含这些参数的列表 我希望能够使用map或类似的东西用相应的参数调用函数 我要调用的函数具有以下类型 runParseTest String gt String gt IO 列表的创建方式如下
  • 如何同时将透镜(或任何其他光学器件)视为吸气剂和设置剂?

    我正在尝试编写一个通用记录更新程序 它允许人们轻松更新记录中的字段existing记录 字段形状相似incoming记录 这是我到目前为止所拥有的 applyUpdater fields existing incoming let gett
  • 在 ghci 下执行 `(read "[Red]") :: [Color]` 时会发生什么?

    我正在阅读以下小节现实世界 Haskell 第 6 章 类型类 http book realworldhaskell org read using typeclasses html关于一个实例Read for Color 它实现了reads
  • 如何让 do 块提前返回?

    我正在尝试使用 Haskell 抓取网页并将结果编译到一个对象中 如果出于某种原因 我无法从页面获取所有项目 我想停止尝试处理页面并提前返回 例如 scrapePage String gt IO scrapePage url do doc
  • 如何在 Haskell 中使 CAF 不是 CAF?

    如何将常量应用形式变成 而不是常量应用形式 以阻止它在程序的生命周期中保留 我尝试过这种方法 Dummy parameter to avoid creating a CAF twoTrues gt Bool twoTrues map Tru
  • 分解大于 100 位的整数 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 X and Y是大于 100 位的整数 求整数P其在范围 X Y 并且保证了 最佳 素数分解 即具有最多的分解 unique主要原因 我所
  • 如何从具有函数依赖关系的类型类中获取和使用依赖类型?

    如何从具有函数依赖关系的类型类中获取和使用依赖类型 为了澄清并给出我最近的尝试的一个例子 从我正在编写的实际代码中最小化 class Identifiable a b a gt b where if you know a you know
  • 由于垃圾收集,Haskell 程序中会出现多长时间的暂停?

    关于我的另一个问题Haskell 集合可以保证每个操作的最坏情况范围 https stackoverflow com q 12393104 1333025 我很好奇 垃圾收集会导致多长时间的暂停 Haskell 是否使用某种增量垃圾收集 以
  • 这是 unsafeCoerce 的安全使用吗?

    我遇到的情况是 我目前正在使用极其可怕的函数 unsafeCoerce 幸运的是 这并不是为了任何重要的事情 但我想知道这是否是该函数的安全使用 或者是否有其他方法可以解决其他人知道的这个特定问题 我的代码类似于以下内容 data Toke
  • 优化 Haskell 内循环

    仍在 Haskell 中进行 SHA1 实现 我现在已经有了一个有效的实现 这是内部循环 iterateBlock Int gt Word32 gt Word32 gt Word32 gt Word32 gt Word32 gt Word3
  • 与 Functor 不同,Monad 可以改变形状?

    我一直很喜欢以下关于单子相对于函子的力量的直观解释 单子可以改变形状 函子不能 例如 length fmap f 1 2 3 总是等于3 然而 对于单子来说 length 1 2 3 gt gt g往往不等于3 例如 如果g定义为 g Nu
  • Prolog中计算数字是否为素数

    我正在尝试计算输入是否是素数 但出了问题 这是我的代码 primeNumber X prime prime A 1 prime prime A B R is A mod B R 1 R A prime prime X B B lt A Ne
  • 这个实例有什么问题:ArrowApply Automaton?

    我希望 Automaton 有实例 ArrowApply 但 Control Arrow Transformer Automaton 没有 我认为下面的代码会表现良好 data Automaton b c Auto runAuto b gt
  • 来自数据类型的 Haskell 随机数

    我对 Haskell 还很陌生 我有一个数据类型 data Sentence Prop Int No Sentence And Sentence Or Sentence deriving Eq 我已经为它写了一个 Show 实例 然而 无论
  • Haskell if-then-else 条件中的“解析输入错误”

    当我尝试编译以下 do 块时 它会抛出错误 输入 conn 上的解析错误 我尝试了许多不同的 if then else 语句配置 但均无济于事 在我添加条件之前 数据库逻辑就起作用了 所以这没有问题 else 中是否有太多行 有没有办法在不
  • Haskell 五个独特的 Wordle 单词

    为了好玩 我正在尝试解决 Matt Parker 在他的 Haskell 频道 Standup Maths in Haskell 频道的链接视频中谈到的与 Wordle 相关的问题 基本上 找到 5 个没有任何共同字母的 5 个字母单词 因
  • seq在haskell中代表什么

    我是 Haskell 的新手 刚刚进入惰性世界编程 我读到seq函数非常特殊 因为它强制使用严格的评估 以便在某些情况下更加有效 但我就是找不到什么seq代表字面意思 也许严格评估Q 它应该提醒您 顺序 或 顺序 因为它允许程序员指定其参数

随机推荐

  • 是否可以在 Django 项目之外更改“migrations”文件夹的位置?

    我想做的是更改 django 项目中特定应用程序的默认迁移路径 将其放在项目本身之外 但保持透明 继续使用进行迁移 and migrate 是否可以 如果是 怎么办 姜戈有一个MIGRATION MODULES环境 它允许您为每个应用程序的
  • Android - 删除工具栏和TabLayout之间的阴影

    我正在尝试做一个布局CollapsingToolbarLayout 但我不明白一件事 我想要去除Toolbar和TabLayout之间的阴影 我尝试了多种方法 但没能消除阴影 有谁能够帮助我 谢谢
  • 这是检测 iPad 的正确方法吗?

    我可以使用以下代码来检测我的应用程序是否在 iPad 上运行吗 我的应用程序需要在 iOS 3 0 或更高版本上运行 if UIDevice currentDevice model isEqualToString iPad Do iPad
  • Windows 任务计划程序安装程序

    我有一个用 c net 编写的小 exe 我想每 24 小时在服务器上运行一次 因此 我自然会使用 Windows 任务计划 而不是自己进行数学计算 我已经创建了该程序 但我想创建一个安装程序来设置所有内容 有没有办法像 Visual St
  • 导航 | IntelliJ IDEA 2017.2 中的类或文件弹出窗口立即关闭

    自从我将 IntelliJ IDEA Community 更新到此版本后 我遇到了一个恼人的问题 IntelliJ IDEA 2017 2 Build IC 172 3317 76 built on July 15 2017 JRE 1 8
  • 在 Docker Jupyter Notebook 的 GUI 中显示卷文件

    我使用 Docker 运行 Jupyter Notebook 并尝试将本地目录安装到预期的 Docker 卷上 但我无法在 Jupyter 笔记本中看到我的文件 Docker 命令是 sudo nvidia docker create v
  • C 编译错误:程序中出现杂散“\200”,并且在数字常量之前出现预期“)”

    我复制了这个程序 但在使用 void downFrequency 函数时遇到了问题 我认为 这是为了Arduino Uno 以下是编译器错误 为 Arduino Uno 编译 MY dds MY dds ino stray 342 in p
  • 具有本机依赖项和复制文件的 Maven 项目

    我有以下场景 mylib 是一个库 我有其源代码 因此我想将它们放入 Maven 项目 mylib mylib 中 这个库有一个 jar 依赖项 我只有 jar 并且在 Maven 存储库中找不到它 而且我也不想在那里安装它 为了使其编译
  • python 字典更新差异

    python 是否有任何内置功能来通知字典更新时哪些字典元素发生了变化 例如 我正在寻找这样的功能 gt gt gt a a hamburger b fries c coke gt gt gt b b fries c pepsi d ice
  • 禁用硬件键 Android ROM

    我想禁用我的自定义 AOSP ROM 中的主页 菜单和后退按钮 我在互联网上搜索过 发现在 out target product generic system usr keylayout 中找到的按键布局文件成功构建后 我可以禁用按钮 我正
  • Eclipse:添加 javadoc

    我通常如何在 eclipse 中为不同的包添加 javadoc 举个例子 我想在 eclipse 中添加 hibernate 的所有 javadoc 但我不知道如何 我读过这篇文章如何在 Eclipse 中添加 hibernate java
  • 按字典顺序对 2d numpy 数组进行排序

    我有一个包含数百列的大型二维数组 我想按字典顺序对其进行排序 即按第一列 然后按第二列 依此类推 直到最后一列 我想这应该很容易做到 但我还没有找到一种快速的方法来做到这一点 这是什么numpy lexsort是的 但是界面很尴尬 向其传递
  • 查找数组中三个多数元素的算法

    假设一个未排序的数组中有三个元素 所有元素出现的次数都超过元素总数的四分之一 找到这些元素最有效的方法是什么 对于这个问题的非在线和在线版本 谢谢你 Edit 我指的非在线版本是 这个数组是完整指定的 在线版本意味着数组元素一次出现一个 我
  • libuv 对 uv_loop_new 的未定义引用

    编译后 我尝试运行libuv示例程序 include
  • 在 Heroku 上禁用 irb 自动完成

    后续行动禁用 irb 自动完成 我想在 Heroku 上禁用 IRB 例如有一个 irbrc with IRB conf USE AUTOCOMPLETE false 在我的 heroku dyno server 的主目录中 我该怎么做 如
  • python3用单反斜杠替换双反斜杠[重复]

    这个问题在这里已经有答案了 我需要更换 with 在python3中是一个复杂的字符串 我知道这个问题已经被问过好几次了 但大多数时候都是针对简单的字符串 因此没有一个 接受的 答案真正适用于复杂的字符串 这也是不同的 from this
  • 如何通过在运行时选择单元测试来运行 CPPUnit 中的单元测试子集?

    我使用 CppUnit 作为单元测试框架 是否可以选择测试用例的子集在运行时执行 CppUnit 中是否提供了过滤选项来适应这种情况 您可能在 main 中调用的 TestRunner run 方法实际上具有可选参数 run std str
  • Javascript正则表达式-exec无限循环

    我正在尝试使用正则表达式获取链接文本 可能有几个链接可能与该模式匹配 我想获得最远的一个直到第四个 这是我的JS代码 var level 1 while match a href a
  • excel中24小时以上的时间表示

    有没有办法在 Excel 中表示时间值 其中小时数可以为 24 及以上 例如 第二天凌晨 1 点的时间为 25 00 00 公共交通调度中的常见表示 它不能只是纯文本 因为我希望能够对它们执行计算 例如平均值 标准差 或绘制图表 情况已经是
  • 为什么这个主要测试这么慢?

    这段代码取自 Haskell Road to Logic Math andProgramming 一书 它实现了埃拉托斯特尼筛法并解决了欧拉计划问题 10 sieve Integer gt Integer sieve 0 xs sieve