可以在Haskell中分析空间使用情况吗

可以在Haskell中分析空间使用情况吗,haskell,Haskell,通过介绍示例函数sumWith提到“提高空间利用率” 我代表了懒惰版本和严格版本,如下所示 sumWith1 v [] = v sumWith1 v (x:xs) = sumWith1 (v+x) xs sumWith2 v [] = v sumWith2 v (x:xs) = (sumWith2 $! (v+x)) xs test = sumWith1 0 [1..200000000] 我想严格版本应该在一定程度上提高性能 我尝试使用GHC分析工具进行验证 $ ghc --make -O

通过介绍示例函数
sumWith
提到“提高空间利用率”

我代表了懒惰版本和严格版本,如下所示

sumWith1 v [] = v
sumWith1 v (x:xs) = sumWith1 (v+x) xs

sumWith2 v [] = v
sumWith2 v (x:xs) = (sumWith2 $! (v+x)) xs

test = sumWith1 0 [1..200000000]
我想严格版本应该在一定程度上提高性能 我尝试使用GHC分析工具进行验证

$ ghc --make -O2 -prof -auto-all -rtsopts -o test1
$ ./test1 +RTS -p -RTS
test
功能中将
sumWith1
更改为
sumWith2
,并作为test2再次执行

以下是分析结果:

通过查看
%alloc
列,我看不到这两个函数之间有任何区别

我的问题是,我应该如何改进测试用例以找到一些差异。 换句话说,是否可以分析这种情况下的空间使用情况


谢谢。

使用GHC的堆分析器


详细描述请参见。这是。

这是您程序的统计数据(我已将上限降低到1000000)

这是你修改过的程序

sumWith1 v [] = v
sumWith1 v (x:xs) = sumWith1 (v+x) xs

sumWith2 v [] = v
sumWith2 v (x:xs) = (sumWith2 $! (v+x)) xs

main = print $ sumWith1 0 [1..1000000]
使用ghc-prof-fprof auto-rtsopts heap.hs编译

对于sumwith1

./heap +RTS -sstderr -K500M
500000500000
     266,384,496 bytes allocated in the heap
     367,442,520 bytes copied during GC
     117,747,616 bytes maximum residency (8 sample(s))
       1,931,472 bytes maximum slop
             196 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0       393 colls,     0 par    0.19s    0.19s     0.0005s    0.0455s
  Gen  1         8 colls,     0 par    0.20s    0.21s     0.0257s    0.0832s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    0.15s  (  0.16s elapsed)
  GC      time    0.39s  (  0.39s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    0.55s  (  0.55s elapsed)

  %GC     time      71.2%  (71.5% elapsed)

  Alloc rate    1,689,230,189 bytes per MUT second

  Productivity  28.7% of total user, 28.7% of total elapsed
对于sumwith2

./heap +RTS -sstderr -K500M           
500000500000
     256,057,488 bytes allocated in the heap
          65,256 bytes copied during GC
          30,240 bytes maximum residency (1 sample(s))
          21,440 bytes maximum slop
               1 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0       488 colls,     0 par    0.00s    0.00s     0.0000s    0.0000s
  Gen  1         1 colls,     0 par    0.00s    0.00s     0.0003s    0.0003s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    0.14s  (  0.14s elapsed)
  GC      time    0.00s  (  0.00s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    0.14s  (  0.14s elapsed)

  %GC     time       1.8%  (1.8% elapsed)

  Alloc rate    1,798,840,354 bytes per MUT second

  Productivity  98.0% of total user, 99.3% of total elapsed

您可以看到GC数量和使用的总内存之间的巨大差异。有关更多信息,您可以参考Don所指出的RWH章节。

您是否尝试过在未进行优化的情况下对其进行编译后进行比较?对于优化,当
test
使用
sumWith1
时,GHC生成一个专门的(type
[Integer]->Integer
)版本,由于严格度分析器知道整数的加法是严格的,因此使用时产生的代码与显式严格的sumWith2得到的代码相同。谢谢Satvik。我将从RWH章节中挖掘更多信息。