像什么时候使用SPECIALIZE
编译指示和它的性能增益。
如果您有一个(类型)多态函数,并且希望它经常在类的一个或几个实例上调用,那么让编译器专门化一个函数。
专业化将字典查找删除使用的位置,并且通常可以进一步优化,类成员函数通常可以内联,然后进行严格分析,两者都可能带来巨大的性能提升。如果唯一可能的优化是消除查询,那么收益一般不会很大。
由于GHC-7,它可能更有效地让功能的{-# INLINABLE #-}
编译,这使得在接口文件中提供的(几乎没有变化,进行一些规范和脱糖)源,因此函数可以专门和甚至可能在呼叫站点内联。
在哪里可以使用RULES
。我听说有人采取特定的规则不开火?我们如何检查?
您可以使用-ddump-rule-firings
命令行选项来检查哪些规则已被触发。这通常会抛出大量已解除规则,因此您必须为自己的规则搜索一下。
您使用规则
当你有一个功能更有效的版本,特殊工种,如
{-# RULES
"realToFrac/Float->Double" realToFrac = float2Double
#-}
当某些功能可以被更有效的版本替换为特殊参数时,例如,
{-# RULES
"^2/Int" forall x. x^(2 :: Int) = let u = x in u*u
"^3/Int" forall x. x^(3 :: Int) = let u = x in u*u*u
"^4/Int" forall x. x^(4 :: Int) = let u = x in u*u*u*u
"^5/Int" forall x. x^(5 :: Int) = let u = x in u*u*u*u*u
"^2/Integer" forall x. x^(2 :: Integer) = let u = x in u*u
"^3/Integer" forall x. x^(3 :: Integer) = let u = x in u*u*u
"^4/Integer" forall x. x^(4 :: Integer) = let u = x in u*u*u*u
"^5/Integer" forall x. x^(5 :: Integer) = let u = x in u*u*u*u*u
#-}
- 重写根据一般规律可能会产生的代码是更好地优化,例如表达式时
{-# RULES
"map/map" forall f g. (map f) . (map g) = map (f . g)
#-}
在后者的样式
广泛使用的RULES
在融合框架制成,例如在text
库,并且该列表的功能在base
中,不同种类的融合(foldr/build
融合)的实施使用规则。
什么时候使函数的参数严格,什么时候可以提供帮助?我明白,严格论证会使参数被评估为正常形式,那么为什么我不应该对所有函数参数加严格?我如何决定?
制作一个参数严格将确保其被评估到弱头部正常形态,不正常的形式。
你不要让所有的参数严格,因为有些功能必须是非严格一些他们的论据在所有的工作,有些是如果不太严格高效的所有参数。
对于examplepartition
必须是非严格在其第二个参数上无限列表在所有的工作,更一般在foldr
使用必须是非严格的第二个参数中的每个函数,在无限列表工作。上有限列表,具有该功能的非严格的第二个参数可以使它显着更有效(foldr (&&) True (False:replicate (10^9) True)
)。
你让争吵严格,如果你知道,在任何有价值的工作可以做反正参数必须进行评估。在许多情况下,GHC的严格性分析器可以自行完成,但当然不是。
一个非常典型的情况是在循环中或尾部递归,其中添加严格防止在途中巨大的thunk建设蓄电池。
我不知道哪里有严格的规定,对我来说这是一个经验问题,过了一段时间,你会学到在哪些地方增加严格度可能会有帮助以及伤害的地方。
作为一个经验法则,这是有道理的,以保持较小的数据(如Int
)评价,但也有例外。
如何查看并检查我的程序中是否有空间泄漏?什么是构成空间泄漏的一般模式?
第一步是使用+RTS -s
选项(如果程序与启用了rtsopts的链接)。这表明你整体使用了多少内存,并且你可以经常判断你是否有泄漏。 (另外,该程序需要与启用rtsopts被链接) 更翔实的输出可从与+RTS -hT
选项,产生一个堆轮廓,可以帮助定位的空间泄漏运行的程序来获得。
如果需要进一步的分析,该程序需要启用分析编译(-rtsops -prof -fprof-auto
,中老年GHCs的-fprof-auto
选项不可用,则-prof-auto-all
选项有最接近的对应)。
然后你运行它与各种分析选项,并查看生成的堆配置文件。
空间泄漏的两个最常见的原因是
第三位可能是采取不必要的共享,GHC做一点公共子表达式消除,但偶尔会在不需要的地方共享长列表。
为了找到泄漏的原因,我再次知道没有硬性规定,有时可以通过在一个地方添加严格性或在另一个地方添加懒惰来修复泄漏。
我该如何看看是否有太多懒惰的问题?我总是可以检查堆分析,但我想知道什么是懒惰伤害的一般原因,示例和模式?
一般来说,懒惰而被通缉,其中结果可以逐步建立起来的,和不想要在没有结果的一部分可以前处理完成,像留下折痕或一般尾递归函数传递。
RHW CH 25? http://book.realworldhaskell.org/read/profiling-and-optimization.html –
@DonStewart谢谢..我已经看过RWH ..问题是我不知道他们做什么,但我并没有对当直觉以及他们的使用是重要的而不重要的地方。我问了这个问题找出其他来源,以进一步加深我的理解。 – Satvik