gpt4 book ai didi

haskell - Runhaskell 性能异常

转载 作者:行者123 更新时间:2023-12-04 05:55:51 25 4
gpt4 key购买 nike

我试图了解在 runhaskell 下运行程序时观察到的性能异常。 .

有问题的程序是:

isFactor n = (0 ==) . (mod n)
factors x = filter (isFactor x) [2..x]
main = putStrLn $ show $ sum $ factors 10000000

当我运行它时,它需要 1.18 秒。

但是,如果我重新定义 isFactor作为:
isFactor n f = (0 ==) (mod n f)

然后程序需要 17.7 秒。

这是性能上的巨大差异,我希望这些程序是等效的。有人知道我在这里想念什么吗?

注意:在 GHC 下编译时不会发生这种情况。

最佳答案

尽管功能应该相同,但它们的应用方式却有所不同。对于第一个定义,isFactor完全应用于调用站点isFactor x .在第二个定义中,它不是,因为现在 isFactor显式接受两个参数。

即使是最小的优化也足以让 GHC 看穿它并为两者创建相同的代码,但是如果您使用 -O0 -ddump-simpl 编译您可以确定,在没有优化的情况下,这会有所不同(至少对于 ghc-7.2.1,YMMV 和其他版本)。

与第一个 isFactor , GHC 创建一个作为谓词传递给“GHC.List.Filter”的函数,调用 mod 10000000(==)内联。对于第二个定义,发生的是 isFactor 中的大多数调用。是对类函数的 let-bound 引用,并且在 isFactor 的多个调用之间不共享.所以有很多完全没有必要的字典开销。

这几乎从来都不是问题,因为即使是默认的编译器设置也会对其进行优化,但是 runhaskell 显然甚至没有做那么多。即便如此,我偶尔也会将代码结构化为 someFun x y = \z ->因为我知道someFun将被部分应用,这是保持调用之间共享的唯一方法(即 GHC 的优化器不够聪明)。

关于haskell - Runhaskell 性能异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9325167/

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