gpt4 book ai didi

使用 GHCi 调试 Haskell 程序中的无限循环

转载 作者:行者123 更新时间:2023-12-03 12:07:34 25 4
gpt4 key购买 nike

我第一次在我正在编写的 Haskell 程序中遇到无限循环。我已经将它缩小到一个非常具体的代码部分,但我似乎无法准确指出我在哪里有一个非终止递归定义。我对 GHCi 中的 :trace 和 :history 有点熟悉,但问题是我的代码的某些分支涉及对 Data.Map.Map 的大量递归修改。从某种意义上说, map xadjust 获得在 map 上找东西x'基于另一个 map 中的值,具体取决于 x' .细节在这里无关紧要,但正如您可能知道的那样,如果这种情况以交织的递归方式发生,我的通话记录将完全陷入 map lookup 中涉及的所有各种比较中。年代,adjust评论和insert ionic 。

谁能推荐一种更有效的方法来定位无限循环?例如,将调用历史限制为来自单个源文件的调用会很有帮助。

最佳答案

我很惊讶没有人提到所有 Haskell 性能问题都会得到的普遍响应(无限运行时是“性能问题”的一个相当极端的例子):分析!

我只是能够使用分析快速识别无限循环。为完整起见,请使用 -prof -fprof-auto 进行编译,然后运行程序足够长的时间,使有问题的函数应该在分析统计中明显。例如,我希望我的程序在 1 秒内完成,所以我让分析器运行大约 30 秒,然后用 Ctrl+C 终止我的程序。 (注意:分析会保存增量结果,因此即使在程序运行完成之前终止程序,您仍然可以获得有意义的数据。编辑:Except when it doesn't.)

在 .prof 文件中,我找到了以下 block :

                                                 individual      inherited
COST CENTRE MODULE no. entries %time %alloc %time %alloc
...
primroot.\ Zq 764 3 10.3 13.8 99.5 100.0
primroot.isGen Zq 1080 50116042 5.3 6.9 89.2 86.2
primroot.isGen.\ Zq 1087 50116042 43.4 51.7 83.8 79.3
fromInteger ZqBasic 1088 0 40.4 27.6 40.4 27.6

所以 primroot.isGen 有 5000 万个条目,而下一个被调用次数最多的函数只有 1024 个调用。此外,99.5% 的运行时间用于计算 primroot ,这似乎非常可疑。我检查了那个函数并很快发现了错误,在我的例子中是一个简单的错字: (`div` foo)而不是 (div foo) .

我认为值得注意的是,GHC 警告不会发现这个问题, -fbreak-on-exceptions .代码库很大;试图通过插入调试语句(任何类型的)来追踪问题并没有让我到任何地方。我也没有成功使用 GHCi 调试器,因为历史基本上不存在,而且 HPC 没有显示任何有用的信息。

关于使用 GHCi 调试 Haskell 程序中的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5337419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com