2016-08-17 18 views
4

データ型がのコンストラクタを持っているとします。大規模代数データ型のメモリフットプリント

data ManyValues 
    = Value0 
    | Value1 
    | Value2 
    ... 
    | Value255 
    | Value256 
    deriving (Show,Eq) 

このデータ型の任意の値のメモリフットプリントはどのくらいですか?私の最初の理解は、各コンストラクタがメモリ内の8ビットワードであることですが、8ビットで可能な値よりも多くのコンストラクタがデータ型にある場合はどうなりますか?コンストラクタは、データ型に存在するコンストラクタの全範囲に対処できるようになるまで、16ビットまでバンプされますか?それとも、私はこれを混ぜ合わせたのですか?

+0

これはあなたを助けるかもしれません:https://stackoverflow.com/questions/3254758/memory-footprint-of-haskell-data-types – Sibi

+0

ありがとう、私は投稿する前にそれを見ました。ゼロフィールドのコンストラクタに関しては、オブジェクトの共有について興味深い点がありますが、8ビットで処理できるコンストラクタよりも多くのコンストラクタ(ゼロフィールドのコンストラクタさえ)がある場合には何が起こるのかについては言及していません。これは、8ビットヘッダーが使用されていると仮定しています。 – carpemb

+6

ああ、その答えでは、ヘッダー "単語"は間違いなく少なくとも32ビットです。もちろん、問題は依然として原則です(例えば、最初の32ビットを使用して選択肢を絞り込む方法があります)が、データ型に2^32のコンストラクタがある場合、他のエンジニアリングの困難に直面する可能性があります。 – pigworker

答えて

3

私が理解しているように、nullaryコンストラクタは1マシンワードの記憶域をとります(つまり、静的に割り当てられたデータへのポインタです)。だから、あなたのデータ構造がそのようなコンストラクタを持っていようと、1,000,000というものであっても、それはまだ1マシン・ワードです。

フィールドを持つコンストラクタは、より多くのスペースを必要としますが、GHCは、その値のすべてのインスタンス間で単一のスタティックシングルトンを共有するための特別なケースのnullコンストラクタを使用します。 (例えば、しか1 Trueプログラム全体である。)もちろん

、サンクは、既存の値(任意値)、GHCが「リダイレクト」ノードとサンクを上書きすると評価される場合、いくらかのスペースを占める。ガベージコレクタは定期的にリダイレクトを削除します。

+0

これはかなり意味があるので、私はこの質問に答えているとマークしています。私が持っていた中核の混乱は、「1機械語」が実際に意味するものであることが判明しました。しかし、私は今、そのことについて自分自身を教育しました。しかし、これはメモリ断片化についてのさらなる疑問を開いた。 – carpemb

+0

nullaryコンストラクタが共有オブジェクトへのポインタに過ぎない場合、実際の呼び出しサイトから非常に遠いオブジェクトを参照することはできません(GCが近くに移動するまで)。そのような場合には、低レベルのデータを、ボックス化されていない線形データ構造のスマートで構築された 'Word32'または' Word64'値として表現するだけで、より低い割り当てとより良いメモリの局所性のためにスペースの効率をあきらめることができます。 – carpemb

+1

なぜ「非常に遠く離れている」ことが問題になるのですか?それは、メモリ地域がどのように機能するかではありません。プログラム内のすべてのnullaryコンストラクタは、移動しない単一の連続したメモリブロック内にあります。それはかなりキャッシュに優しいはずです。 – MathematicalOrchid