6

最初は、次のようなコードがありました。

data Something = Something !Word32 !Word32

retrieveSomething :: Socket -> IO (Something)
retrieveSomething sock = do
    ...

function sock = do
    (Something x y) <- retrieveSomething sock
    let (a,b,c) = case x of
      0 -> (foo,bar,baz)
      1 -> (foo2,bar2,baz2)
      ...

    doIOwithParams a b c

-hy -hC"..."これをRTSオプションでプロファイリングしました。

(# a,b,c #)ヒーププロファイルを見ると、3タプルを使用するとメモリが大量に消費されることがわかったため、複数の値を返すのに適していると思われるボックス化されていないタプル拡張機能(つまり)を使用しました。

stuffボックス化されていないタプルを試す前に明示的な呼び出しを行ってテストしたため、ヒープの使用量がほぼ減少したと確信していますが、そうすることで、コストセンターに割り当てられたさまざまなタイプの値を監視できなくなりました。

問題をもう少し明確にするために、ボックス化されていないタプルを使用せずにアプリケーションをプロファイリングした後、Somethingタイプ(およびその他のもの)のスペース値がヒープにどの程度取り込まれたかを確認できました。現在、ヒープグラフに表示されるタイプは1つだけです。これは、関数呼び出しで行っている可変ハッシュテーブル呼び出しに関連していると思われます。

これを修正する方法はありますか?

編集:ボックス化されていないタプルがプロファイルに表示されないことは完全に理にかなっていますが、それらを使用すると、関数呼び出し/コストセンターで他のすべてが非表示になる理由についてはまだ混乱しています。

ボックス化されていないタプルを使用するのではなく、明示的な呼び出しを使用してプロファイリングを試みました。

    case x of
      0 -> doIOwithParams foo bar baz
      1 -> doIOwithParams foo2 bar2 baz2

3タプルのオーバーヘッドを確認できるようになっただけでなく、関数で使用されている何かや他のすべてのタイプも表示されます。これは、ノードタイプしか表示できないボックス化されていないタプルの場合とは異なります(これは、他のタイプと比較してスペースをほとんどとらない、私が使用しているハッシュテーブルに関連している場合と関連していない場合があります。

4

1 に答える 1

4

3タプルを使用するとメモリが消費されすぎるのを見ていたので、複数の値を返すのに適していると思われるボックス化されていないタプル拡張機能(つまり、(#a、b、c#))を使用しました。

厳密なフィールドを持つ通常のデータ型を使用するだけです。次に、GHCは、適切と思われるスタック上のヒープまたはボックス化されていないタプルにマップできます。

data Something = Something {-# UNPACK #-}!Word32 {-# UNPACK #-}!Word32

これには、ボックス化されていないタプルのすべての利点があり、欠点はありません。

于 2013-02-24T12:56:39.420 に答える