Here is the full repository。这是一个非常简单的测试,它使用postgresql-simple数据库绑定将50000个随机事件插入到数据库中。它使用MonadRandom并可以生成事物。这段代码为什么会消耗这么多堆?
Here is the lazy 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
Here is case2,这只是转储到标准输出:
main = do
ts <- genThings
mapM print $ take 50000 ts
在第一种情况下,我有非常不好的GC时间:使用的东西产生的代码
Here is case1和特定片段
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
我试图应用堆分析,但没有任何理解。它看起来像所有50000个东西都先在内存中构建,然后通过查询转换为ByteStrings,然后将这些字符串发送到数据库。但为什么会发生?我如何确定有罪代码?
GHC版本7.4.2
汇编标志是-02为我检查轮廓与formatMany和50k的东西全部库和包本身(由小集团-dev的沙箱中的编译)
我不明白你的第一和第二种情况之间的代码是不同的。你可以发布1)自包含的代码,或者至少明确说明这些情况是什么2)GHC版本3)编译器标志。 –
这对我来说几乎没有堆 - 你没有优化编译?这将是一个问题。 –
我重新编译了所有带有-O2但不起作用的库 – s9gf4ult