[解決済み] Haskellデータ型のメモリフットプリント
質問
Haskellで(主にGHCで)あるデータ型の値を格納するために必要な実際のメモリ量を見つけるにはどうしたらよいでしょうか?実行時に評価することは可能ですか(例えばGHCiで)、それとも複合データ型のメモリ要件をその構成要素から推定することは可能ですか?
一般的に、もし型のメモリ要件が
a
と
b
のような代数的データ型のメモリオーバーヘッドがわかっている場合、どのようになりますか?
data Uno = Uno a
data Due = Due a b
例えば、これらの値はメモリ上で何バイトを占めているのでしょうか?
1 :: Int8
1 :: Integer
2^100 :: Integer
\x -> x + 1
(1 :: Int8, 2 :: Int8)
[1] :: [Int8]
Just (1 :: Int8)
Nothing
ガベージコレクションの遅延により、実際のメモリ割り当て量が多くなることは理解しています。遅延評価により大幅に異なる可能性があります(サンクサイズは値のサイズとは関係ありません)。問題は、あるデータ型が与えられたとき、その値が完全に評価されたときにどのくらいのメモリを消費するかということです。
があることがわかりました。
:set +s
オプションがありますが、単一の値のメモリフットプリントを推定する方法は明らかではありません。
どのように解決するのですか?
(以下はGHCに適用されるもので、他のコンパイラは異なる保存規約を使用しているかもしれません)
経験則です。
コンストラクタはヘッダに1ワード、各フィールドに1ワードを消費します。
. 例外: フィールドを持たないコンストラクタ (例えば
Nothing
または
True
はスペースを取りません。GHC はこれらのコンストラクタのインスタンスを一つ作成し、すべての用途で共有するからです。
1ワードは32ビットマシンでは4バイト、64ビットマシンでは8バイトです。
ですから、例えば
data Uno = Uno a
data Due = Due a b
アン
Uno
は2つの単語を必要とし
Due
は3つ取ります。
は
Int
型は次のように定義されています。
data Int = I# Int#
今すぐ
Int#
は1つの単語を取るので
Int
は合計で2語を取ります。 ほとんどの非ボックス型は1語で済みますが、例外として
Int64#
,
Word64#
そして
Double#
(32ビットマシンの場合)は2を取ります。 GHC は実際には、小さな値のキャッシュを持っています。
Int
と
Char
であるため、多くの場合これらはヒープスペースを全く必要としません。 A
String
を使用しない限り、リストセルのためのスペースしか必要としません。
Char
s > 255を使用しない限り、リストのセルだけがスペースを必要とします。
アン
Int8
と同じ表現になります。
Int
.
Integer
はこのように定義されます。
data Integer
= S# Int# -- small integers
| J# Int# ByteArray# -- large integers
ということで、小さな
Integer
(
S#
) は2ワードで済みますが、大きな整数はその値に応じて可変のスペースを必要とします。 A
ByteArray#
は2語(ヘッダ+サイズ)と配列自体のためのスペースを取ります。
以下のことに注意してください。
で定義されたコンストラクタは
newtype
は自由です。
.
newtype
は純粋にコンパイル時のアイデアであり、実行時には何のスペースも取らず、何のインストラクションも要しません。
より詳細な情報は GHCの解説におけるヒープオブジェクトのレイアウト .
関連
-
[解決済み] エラー haskell: スコープ内にありません。どういう意味ですか?
-
[解決済み] .の違いは何ですか?(ドット)と$(ドルマーク)の違いは何ですか?
-
[解決済み] Haskellで大規模設計?[クローズド]
-
[解決済み】ローカル変数のメモリはスコープ外からアクセスできる?
-
[解決済み】代数的なデータ型の代数を悪用する - なぜこれが有効なのか?
-
[解決済み] Haskellで副作用がモナドとしてモデル化されているのはなぜですか?
-
[解決済み】Haskellの入門編
-
[解決済み] TLSサーバーを実装するためのHsOpenSSL APIの適切な使用法
-
[解決済み] Haskellでグラフはどのように表現するのか?
-
[解決済み] なぜ遅延評価が有効なのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン