Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 为什么这段代码要消耗这么多堆?_Haskell_Profiling_Heap_Space Leak - Fatal编程技术网

Haskell 为什么这段代码要消耗这么多堆?

Haskell 为什么这段代码要消耗这么多堆?,haskell,profiling,heap,space-leak,Haskell,Profiling,Heap,Space Leak,。这是一个非常简单的测试,它使用postgresql简单数据库绑定将50000个随机内容插入数据库。它使用MonadRandom,可以懒洋洋地生成东西 以及使用Thing generator的特定代码片段: insertThings c = do ts <- genThings withTransaction c $ do executeMany c "insert into things (a, b, c) values (?, ?, ?)" $ map (\(Thin

。这是一个非常简单的测试,它使用postgresql简单数据库绑定将50000个随机内容插入数据库。它使用MonadRandom,可以懒洋洋地生成东西

以及使用Thing generator的特定代码片段:

insertThings c = do
  ts <- genThings
  withTransaction c $ do
    executeMany c "insert into things (a, b, c) values (?, ?, ?)" $ map (\(Thing ta tb tc) -> (ta, tb, tc)) $ take 50000 ts
而在第二种情况下,时间很好:

cabal-dev/bin/dumptest +RTS -s > out
   1,492,068,768 bytes allocated in the heap
       7,941,456 bytes copied during GC
       2,054,008 bytes maximum residency (3 sample(s))
          70,656 bytes maximum slop
               6 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0      2888 colls,     0 par    0.13s    0.16s     0.0001s    0.0089s
  Gen  1         3 colls,     0 par    0.01s    0.01s     0.0020s    0.0043s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    2.00s  (  2.37s elapsed)
  GC      time    0.14s  (  0.16s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    2.14s  (  2.53s elapsed)

  %GC     time       6.5%  (6.4% elapsed)

  Alloc rate    744,750,084 bytes per MUT second

  Productivity  93.5% of total user, 79.0% of total elapsed
我曾尝试应用堆分析,但什么都不懂。看起来所有的50000个字符串都是首先在内存中构造的,然后通过查询转换成bytestring,然后将这些字符串发送到数据库。但为什么会这样呢?我如何确定有罪的代码

GHC版本为7.4.2


编译标志是所有库和包本身的-O2(由cabal dev在sandbox中编译)

我已经用formatMany和50k东西检查了配置文件。记忆逐渐积累,然后迅速下降。使用的最大内存略高于40mb。主要成本中心是buildQuery和escapeStringConn,其次是toRow。一半的数据是ARR_字(字节字符串)、操作和列表

formatMany
通过testring从嵌套的动作列表中组合的片段,几乎可以生成一个长的
ByteString
。操作被转换为
ByteString
生成器,这些生成器保留
ByteString
,直到用于生成最终的long strict
ByteString
。 这些BYTESTRING的使用寿命很长,直到最终BS建成为止

字符串需要用libPQ转义,因此任何非普通操作
BS
都会传递给libPQ,并在escapeStringConn和friends中替换为新操作,从而添加更多垃圾。 若用另一个Int替换Thing中的文本,GC时间将从75%下降到45%

我试图通过formatMany和buildQuery来减少临时列表的使用,用foldM over Builder替换mapM。这没有多大帮助,但会稍微增加代码的复杂性

TLDR-
Builders
不能被懒散地使用,因为它们都需要生成最终严格的
ByteString
(相当于字节数组)。
如果内存有问题,请在同一事务中将executeMany拆分为多个块。

我不明白第一种情况和第二种情况的代码有什么不同。你能发布1)自我包含的代码或至少明确说明案例是什么2)GHC版本3)编译器标志吗?这对我来说几乎不使用堆-你是在没有优化的情况下编译的吗?这将是一个问题。我已经用-O2重新编译了所有库,但没有效果。我自己解决了这个问题,但不是很清楚。构建器也可以生成惰性bytestring,但遗憾的是libPQ不使用惰性字符串。这是haskell的ByteStrings中真正愚蠢的问题。
cabal-dev/bin/posttest +RTS -s       
   1,750,661,104 bytes allocated in the heap
     619,896,664 bytes copied during GC
      92,560,976 bytes maximum residency (10 sample(s))
         990,512 bytes maximum slop
             239 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0      3323 colls,     0 par   11.01s   11.46s     0.0034s    0.0076s
  Gen  1        10 colls,     0 par    0.74s    0.77s     0.0769s    0.2920s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    2.97s  (  3.86s elapsed)
  GC      time   11.75s  ( 12.23s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time   14.72s  ( 16.09s elapsed)

  %GC     time      79.8%  (76.0% elapsed)

  Alloc rate    588,550,530 bytes per MUT second

  Productivity  20.2% of total user, 18.5% of total elapsed
cabal-dev/bin/dumptest +RTS -s > out
   1,492,068,768 bytes allocated in the heap
       7,941,456 bytes copied during GC
       2,054,008 bytes maximum residency (3 sample(s))
          70,656 bytes maximum slop
               6 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0      2888 colls,     0 par    0.13s    0.16s     0.0001s    0.0089s
  Gen  1         3 colls,     0 par    0.01s    0.01s     0.0020s    0.0043s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    2.00s  (  2.37s elapsed)
  GC      time    0.14s  (  0.16s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    2.14s  (  2.53s elapsed)

  %GC     time       6.5%  (6.4% elapsed)

  Alloc rate    744,750,084 bytes per MUT second

  Productivity  93.5% of total user, 79.0% of total elapsed