首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Runhaskell性能异常

Runhaskell性能异常
EN

Stack Overflow用户
提问于 2012-02-17 16:40:11
回答 2查看 331关注 0票数 8

我正在尝试理解在runhaskell下运行程序时观察到的性能异常。

正在讨论的程序是:

代码语言:javascript
复制
isFactor n = (0 ==) . (mod n)
factors x = filter (isFactor x) [2..x]
main = putStrLn $ show $ sum $ factors 10000000

当我运行这段代码时,需要1.18秒。

但是,如果我将isFactor重新定义为:

代码语言:javascript
复制
isFactor n f = (0 ==) (mod n f)

那么这个程序需要17.7秒。

这是一个巨大的性能差异,我希望这些程序是等价的。有人知道我错过了什么吗?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-17 20:48:54

虽然这些函数应该是相同的,但它们的应用方式是不同的。对于第一个定义,在调用站点isFactor x上完全应用了isFactor。在第二个定义中,它不是,因为现在isFactor显式地接受两个参数。

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

对于第一个isFactor,GHC创建了一个单独的函数,该函数作为谓词传递给"GHC.List.Filter",同时内联了对mod 10000000(==)的调用。对于第二个定义,isFactor中的大多数调用都是对类函数的let绑定引用,并且不会在多次isFactor调用之间共享。所以有很多字典开销是完全不必要的。

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

票数 9
EN

Stack Overflow用户

发布于 2012-02-17 17:23:21

据我所知,runhaskell几乎没有做任何优化。它的设计目的是快速加载和运行代码。如果它做了更多的优化,你的代码开始运行需要更长的时间。当然,在这种情况下,优化后的代码运行得更快。

据我所知,如果存在代码的编译版本,则runhaskell将使用它。因此,如果性能对你来说很重要,只需确保你在编译时首先打开了优化。(我认为您甚至可以将开关传递给runhaskell以启用优化-您必须查看文档...)

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9325167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档