此代码泄漏或不依赖于我如何编译相同的RWS实现:
import Control.Monad (replicateM_)
import qualified Control.Monad.RWS.CPS as RWS
import Data.Monoid (Sum (..))
-- import qualified RWS
{-# ann module "HLint: ignore Use camelCase" #-}
count_a_lot :: Int -> RWS.RWS () (Sum Int) () ()
count_a_lot = flip replicateM_ count
count :: RWS.RWS () (Sum Int) () ()
count = RWS.tell . Sum $ 1
main :: IO ()
main = print . snd $ RWS.evalRWS (count_a_lot 10000000) () ()
Run Code Online (Sandbox Code Playgroud)
我尝试了两种使用CWS版本的RWS的方法:
import qualified Control.Monad.RWS.CPS as RWS使用writer-cps-transformersnixpkgs中的软件包。import qualified RWS使用Internal.hs,逐字复制RWS.hs到与上面粘贴的文件相同的本地目录中。如果我编译上面的代码并运行它,我可以看到它在恒定空间中运行。
如果我更改导入以编译并链接副本 RWS.hs
import Control.Monad (replicateM_)
-- import qualified Control.Monad.RWS.CPS as RWS
import Data.Monoid (Sum (..))
import qualified RWS
Run Code Online (Sandbox Code Playgroud)
我发生空间泄漏。黑色的固定器是(103)<*>.\,蓝色的是SYSTEM
为什么会这样呢?还是我该如何最好地调试呢?
在这两种情况下,我都使用ghc(no cabal)进行编译-Wall -O2 -prof -fprof-auto -rtsopts -fexternal-interpreter。如果相关,我可以发布更详细的编译器调用和输出行。
使用ghc-8.4.4,transformers-0.5.5.0和writer-cps-transformers-0.1.1.4。我知道这些版本不是最新版本,但是我有兴趣知道发生了什么事情,而不是解决实际的泄漏,因此我认为这些版本无关紧要。
事实上,罪魁祸首是分析系统。请注意,您实际上不需要-prof检测空间泄漏\xe2\x80\x94,RTS 选项-s可以在没有它的情况下打印出“总内存”测量结果。不太科学的是,空间泄漏使程序变慢很多,你可以感觉到。有了这个,我发现禁用将-prof“本地”版本的内存使用量减少到 2MB(与“库”版本相同),并保留已用的约 1.9GB。
分析会使事情变慢的原因是 GHC 也拒绝优化。它无法再积极地重组您编写的代码,因为成本中心暗示了代码的某种结构,有时优化后成本中心没有合适的位置,从而阻碍了优化。要准确地知道这里出了什么问题,需要知道构建库所用的标志,但高级解释是,库是用writer-cps-transformers比文件更不积极的分析(因此更积极的优化)构建的RWS.hs。-fprof-auto是一个非常激进的分析选项,它很容易破坏许多优化。如果我使用writer-cps-transformers内置的-fprof-auto,我会遇到同样的问题。如果我使用RWS.hs不进行分析或使用较弱的东西(例如 )-fprof-auto-exported,那么我可以解决问题。
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |