- - PR -
構造体とクラスの選択
投稿者 | 投稿内容 | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-09-28 03:21
わたしには16 バイト未満というのは目安だと感じられます。 値型のサイズが大きくなればなるほど、コピーのコストが大きくなるし、 知らない間に大量のメモリを消費していたりしますから。(先の投稿の「2.List(初期量指定なし)」のように)
ジェネリックを使っていればボックス化が発生するような場面はそうないですよね!?
先のプロファイルから、いい線いっていたようです。
「管理ヒープ」上にオブジェクトが割り当てられるだけで、全部を管理しているわけではないようです。 →ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part I GCハンドル(強い参照(ルート)・弱い参照(長い、短い)・ピン)はハンドルテーブルにて管理されています。
パフォーマンスにどれだけ影響あるでしょう?私には完全に無視できる程度だと思いますが。
ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part IIより引用
まあ、連続領域に配置されても、フラグメンテーションは発生するでしょうが・・・GCがメモリコンパクションしてくれるわけですし。しかも世代別GCで。
構造体かクラスか/値型か参照型か を格納するコレクションで決めるなんてナンセンスだと思いますけど!? .NETクラスライブラリのコレクションの実装は、いたってフツーな実装ですよ。 コレクションの特徴(追加挿入の得意不得意、ランダムアクセスの得意不得意・・・)を知らずに使うほうが よっぽど問題だと思います。 | ||||||||||||||||||||||||||||||||
|
投稿日時: 2008-09-30 22:00
ジェネリック コレクション クラスが参照型なので、発生していると思います→2008-09-24 22:02
「パフォーマンス」と一口に言っても、いろいろあります。どのような、パフォーマンスでしょう? ガーベッジコレクションは別スレッドで行われるので、メモリの要求を出したときにコレクトが行われるような状況でなければ、特に問題はないと思われます。 構造体が大きくなれば、Boxing - UnBoxing でコピーにかかる時間がそれだけ多くなりますから、参照を2回たどることとどちらがパフォーマンス的に不利かというと、構造体のような気がします。 ところで、ご質問の背景は、「コーディング規約を策定中。できるだけ、実行速度的なパフォーマンスがよいコードとなるような規約にしたい。」でしょうか? もしそうなら、コーディング規約には、まずは「一貫性」を求めるべきかと思います。この一貫性は、「どのようなレベルの人でも、基本的に同じコードを書ける。より高技術の人は、技術力のない人にも読み解ける範囲で、高度な書き方を選べる。」ということです。実行速度的なパフォーマンスについては、「構造体だと云々。クラスだと云々。」という Tips として選択できるようにしておく方がよいと思います。 もし、「この場合はクラス、この場合は構造体を用いること」と規定すると、どちらにしようか迷うケースが出てきます。この、「迷う」状態は、コードの一貫性を保つことを難しくし、また、読みにくくさせます。そして、クラスや構造体のメンバーを変更したとき、規約によって、クラスと構造体を入れ替えなければならなくなるかもしれません。このとき、修正に伴うコストは、とても大きなものとなるでしょう。 ここで、「パフォーマンス」を「実行速度的な」と修飾していることに注意してください。「コード ライティングのパフォーマンス」を見ると、統一してある方が良くなるでしょう | ||||||||||||||||||||||||||||||||
|
投稿日時: 2008-10-01 05:33
おはようございます。
ちょっと意味がわからないのですが、 2008-09-24 22:02のJittaさんの投稿についてですが、…
ここで示されたコードって、ボックス化とは無関係ですよね!? ひろしさんがすでに回答されているとおり、 「構造体は値型なので、値そのものがコピーされます。」 が、謎の答えでしょう。 一応、確認しておきますが、「ボックス化」とは… ボックス化とボックス化解除 (C# プログラミング ガイド)より引用
ということです。 通常、値型はそれ単体ではマネージ ヒープに割り当てられることはありません。 (配列やクラスのフィールドという形ではマネージ ヒープ上に乗っかります。) しかし、ボックス化が発生した場合は、上記の引用の通りマネージ ヒープに格納されます。 つまりマネージ ヒープに値型が単体で割り当てられたかどうかを(プロファイラで)調べることによって、 ボックス化が発生したかどうかを確認することが可能です。 JittaさんのコードでCLR Profilerで検証してみると、 構造体Aのヒープ上の割り当ては見当たりません。 ボックス化は発生していないと見て取れます。 このコードを非ジェネリックのArrayListに変更すると… 120bytes - 10 instances, 12byte の割り当てを確認できます。 この場合はボックス化が発生しています。
| ||||||||||||||||||||||||||||||||
|
投稿日時: 2008-10-01 07:48
オオボケしてました。すみません。
| ||||||||||||||||||||||||||||||||
|
投稿日時: 2008-10-02 17:39
Tdnr_SymさんJittaさん
良いアドバイスありがとうございます。Tdnr_SymさんやJittaさんの議論を拝見する中で視点が広げることができました。プロファイリングの大切さも改めて認識しました。 |