2016-07-17 9 views
0

私はジョゼフ・アルバハリとベンAlbahari(オライリー)の本クラス変数を宣言する順序は、メモリの割り当て方法に影響しますか?

から抜粋一言でC#6.0、次のように出くわしました。

Copyright 2016 Joseph AlbahariとBen Albahari、978-1-491-92706-9。

enter image description here

経験則として、そして、私はそれがそこに言及表示されていないが、それは従わないだろう - あなたはいつものサイズの降順であなたのタイプの変数を宣言する必要がありこと、順番にメモリの浪費を避けるためにが指摘されていますか?

私はそれが正しいとすれば、私たちはすべて、通常、タイプを設計するときにそれを考慮しなければならないということです。


更新:

私は上記のが正しいか間違っているかどうかを証明するために、次のスニペットを思い付きました。しかし、私はS2のサイズが異なると予想していました(本の説明を支持するため)。

public struct S1 
{ 
    public byte b; 
    public long l; 
} 

public struct S2 
{ 
    public long l; 
    public byte b; 
} 

[StructLayout(LayoutKind.Explicit, Size = 9)] 
public struct S3 
{ 
    [FieldOffset(0)] 
    public byte b; 

    [FieldOffset(1)] 
    public long l; 
} 

S1 s1 = new S1(); 
S2 s2 = new S2(); 
S3 s3 = new S3(); 

Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(s1)); //prints 16 
Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(s2)); //prints 16 
Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(s3)); //prints 9 
+0

"あなたのタイプでは、サイズの降順で"かなりありません。パッキングの観点から、 'short、short、int、long'は' long、int、short、short'と同じくらい良いです。メモリを削減するためにデータを最適化すると、パフォーマンスに重大な影響が生じることに注意してください。 – AlexD

+0

@AlexD:あなたのビットを追加していただきありがとうございます。メモリを浪費しないように心がけ、上記のガイドラインに従うことで、パフォーマンスに重大な影響がもたらされるかどうかを詳しく説明できますか? – Veverke

+1

私はCPUがワードサイズよりも小さいデータを扱うのを好まないと確信していますので、スペースを節約できるかもしれませんが、パフォーマンスは低下します – MickyD

答えて

4

本の抜粋はかなり誤解を招いています。これは、7バイトが「無駄」であることを意味しますが、フィールドの順序とは関係ありません。あなたは、最初にlongのメンバーを入れて、注文を交換することを考えます。しかし、それは何も達成されません、それらの7バイトはまだ未使用です。

構造体のレイアウトとサイズは、長さがの場合でも、が配列内で8になるように計算されます。言い換えれば、A []の要素は整列を必要とする。これは構造体が16バイトの場合にのみ機能します。つまり、フィールドをスワップするだけで、未使用の7バイトが構造体の最後に移動します。

C#の構造体には、暗黙の[StructLayout(LayoutKind.Sequential)]属性があります。 LayoutKind.Explicitを使用して、フィールドの意図的な位置揃えを強制的に行う必要があります。コストに注意してください。フィールドの位置がずれているとかなり高価になり、読み取りと書き込みが3倍も遅くなります。フィールドがL1キャッシュライン境界に跨ったときに起こります。そして、プロセッサがミスアライメントされたアクセスをサポートしていない場合は、Itaniumがピクチャから抜け出している今日の問題はあまりありません。また、CLR仕様から得られるアトミック性の保証は失われます。ガベージコレクタを破棄する参照型(文字列など)のフィールドを意図的に整列させることはできません。

構造体に3つ以上のメンバーがある場合は、少し面白いです。今すぐ注文することができます。バイト、long、intのように、その順序で20バイトかかるでしょう。あなたが16バイトを取るよりもむしろbyte、intに再配置すると、intはパディングに収まります。 LayoutKind.Autoでオーバーライドすると、CLRがこれを行います。

+0

ハンス、あなたは具体的には構造体について話していますが、私が理解していることから、この動作はStructsに限定されていません。著者はカスタムタイプ(クラス)でも同様のことが起こっていると主張しています。 – Veverke

+2

クラスは常にLayoutKind.Autoをデフォルトで持っていますので、すでに最適なレイアウトを取得しています。他のすべては同じです。 –

+0

ああ、よろしくお願いします。ありがとう。 – Veverke

関連する問題