Tag: ghc

GHC可以预期哪些优化可靠地执行?

GHC有很多可以执行的优化,但是我不知道它们是什么,也不知道它们在什么情况下被执行。 我的问题是:我可以期待什么样的转变,每一次或几乎这样呢? 如果我看一段经常被执行(评估)的代码,我的第一个想法是“嗯,也许我应该优化它”,在这种情况下,我应该第二个想法是“甚至不要去想它, GHC得到这个“? 我正在读“ Stream Fusion:从List到Streams到Nothing”一文 ,以及他们用于将列表处理重写为不同forms的技术,GHC的正常优化将可靠地优化为简单循环,这对我来说是新颖的。 如何知道我的程序何时可以进行这种优化? GHC手册中提供了一些信息 ,但它只是回答这个问题的一部分。 编辑:我开始赏金。 我想要的是像lambda / let / case-floating,types/构造函数/函数参数专门化,严格分析和拆箱,worker / wrapper,以及其他重要的GHC所做的我已经省略的低级转换列表,以及input和输出代码的解释和实例,并且当总效应大于其部分总和时,理想地说明情况。 理想的情况下,提到什么时候转型不会发生。 我并不期望对每一个转换都有新颖的解释,只要大局就是这样,几句话和一行代码就足够了(或者是一个链接,如果不是二十页的科学论文)清除它的结尾。 我希望能够看到一段代码,并能够很好地猜测它是否会被编译成一个紧密的循环,或者为什么不是,或者我将不得不改变来做出来。 (我对stream融合这样的大型优化框架(我只是读了一篇关于这方面的文章)并不是很感兴趣;更多的是写这些框架的人所拥有的知识。

-XAllowAmbiguousTypes何时适合?

我最近发布了一个有关share定义的关于语法-2.0的问题。 我已经在GHC 7.6中工作了: {-# LANGUAGE GADTs, TypeOperators, FlexibleContexts #-} import Data.Syntactic import Data.Syntactic.Sugar.BindingT data Let a where Let :: Let (a :-> (a -> b) :-> Full b) share :: (Let :<: sup, sup ~ Domain b, sup ~ Domain a, Syntactic a, Syntactic b, Syntactic (a -> b), SyntacticN (a -> (a -> b) […]

跟踪约束的技巧

这里是这样的情景:我写了一些代码和一个types签名,GHC抱怨不能推导出一些x和y 。 您通常可以将GHC扔到骨头上,并简单地将同构添加到函数约束中,但出于以下几个原因,这是一个糟糕的主意: 它不强调理解代码。 你可以在5个约束条件下得到足够的结果(例如,如果5个约束被一个更具体的约束所暗示) 如果你做错了什么,或者GHC是无益的,你最终可能会受到假约束 我刚刚花了几个小时来处理案例3.我玩的是syntactic-2.0 ,我试图定义一个域独立版本的share ,类似于NanoFeldspar.hs定义的版本。 我有这个: {-# LANGUAGE GADTs, FlexibleContexts, TypeOperators #-} import Data.Syntactic — Based on NanoFeldspar.hs data Let a where Let :: Let (a :-> (a -> b) :-> Full b) share :: (Let :<: sup, Domain a ~ sup, Domain b ~ sup, SyntacticN (a -> (a -> […]

GHC中自动专业化的传递性

从GHC 7.6 文档 : [Y]你通常甚至不需要SPECIALIZE附注。 当编译一个模块M时,GHC的优化器(带有-O)会自动考虑在M中声明的每个顶层重载函数,并且专门针对它在M中调用的不同types。优化器还考虑每个导入的INLINABLE重载函数,并专门针对它在M中被称为的不同types 和 此外,给定一个函数f的SPECIALIZE pragma,GHC将自动为f调用的任何类重载函数创build专门化,如果它们与SPECIALIZE pragma在同一个模块中,或者它们是INLINABLE; 等等。 因此,GHC应该自动地专门化一些标记为INLINABLE 一些/ most / all(?)函数而没有附注,如果我使用一个明确的附注,专门化是传递的。 我的问题是: 汽车专业化传递? 具体来说,这是一个小例子: Main.hs: import Data.Vector.Unboxed as U import Foo main = let y = Bar $ Qux $ U.replicate 11221184 0 :: Foo (Qux Int) (Bar (Qux ans)) = iterate (plus y) y !! 100 in putStr $ […]

Haskell / GHC中的`forall`关键字是做什么的?

我开始了解如何在所谓的“存在types”中使用forall关键字: data ShowBox = forall s. Show s => SB s 然而,这只是一个子集,因为它是如何使用的,而我根本无法把它用在这样的事情上: runST :: forall a. (forall s. ST sa) -> a 或者解释为什么这些不同: foo :: (forall a. a -> a) -> (Char,Bool) bar :: forall a. ((a -> a) -> (Char, Bool)) 或者整个RankNTypes东西… 我倾向于select清晰,不含行话的英语,而不是学术环境中正常的语言。 我试图阅读的大部分解释(我可以通过search引擎find的)有这些问题: 他们不完整。 他们解释了使用这个关键字(比如“存在types”)的一部分,这让我感觉很开心,直到我读完以不同的方式使用它的代码(比如runST , foo和bar )。 他们密集的假设,我已阅读离散math的任何分支,类别理论或抽象代数本周stream行的最新。 (如果我再也不读“实施细节咨询文件”,那就太快了。) 他们的写作方式经常会把简单的概念变成扭曲和破碎的语法和语义。 所以… 谈到实际的问题。 […]

用GHC编译的小Haskell程序变成了巨大的二进制文件

即使是小的Haskell程序也变成了巨大的可执行文件。 我已经编写了一个小程序,这个程序是用GHC编译的,大小为7MB。 什么可以导致一个小的Haskell程序被编译成巨大的二进制文件? 如果有的话,我能做些什么来减less这种情况?

读GHC核心

核心是GHC的中间语言。 阅读核心可以帮助你更好地理解你的程序的性能。 有人问我阅读Core的文档或教程,但我找不到太多。 什么文件可用于阅读GHC核心? 这是我到目前为止发现的: 写Haskell跟C一样快:利用严格性,懒惰和recursion 哈斯克尔和C一样快:在高空工作以降低性能 RWH:第25章。分析和优化 CUFP高性能Haskell讲​​座 (幻灯片65-80)

什么时候GHC Haskell自动记忆?

我不明白为什么m1显然是memo而m2不在以下内容: m1 = ((filter odd [1..]) !!) m2 n = ((filter odd [1..]) !! n) 在第一次调用时,m1 10000000需要大约1.5秒,而后续调用的一小部分(大概是caching列表),而m2 10000000总是花费相同的时间(每次调用重build列表)。 任何想法发生了什么? GHC是否和何时将记忆function有什么经验法则? 谢谢。

Haskell数据types的内存占用

我如何find在Haskell中存储一些数据types的值所需的实际内存量(主要是GHC)? 是否有可能在运行时(例如在GHCi中)对其进行评估,还是有可能从组件中估计组合数据types的内存需求? 通常,如果typesa和b内存需求是已知的,那么代数数据types的内存开销是多less,例如: data Uno = Uno a data Due = Due ab 例如,这些值占用内存中有多less个字节? 1 :: Int8 1 :: Integer 2^100 :: Integer \x -> x + 1 (1 :: Int8, 2 :: Int8) [1] :: [Int8] Just (1 :: Int8) Nothing 我知道实际的内存分配比较高,因为垃圾回收的延迟。 由于懒惰评估可能会有很大的不同(并且thunk的大小与值的大小无关)。 问题是,在给定数据types的情况下,在完全评估时它的值需要多less内存? 我发现GHCi中有一个:set +s选项来查看内存统计信息,但不清楚如何估计单个值的内存占用情况。