2016-09-13 5 views
0

Resharperは私が気づいていなかった自分の.net構造体への変更を推奨しました。私は苦労してについてのMicrosoftの情報を見つけ出していますthis()構造体の初期化子。C#Struct this()イニシャライザ - メモリ、パフォーマンス、およびクリーン

私は値を渡している構造体上にコンストラクタを持っていますが、一度構造体が作成されると構造体のプロパティを読み込み専用にします。 Resharperは提案された方法により、コードをもっときれいに見えるようにします。

質問:

  • メモリ:私は可能であれば余分なゴミの発生を回避したいです。私はこの()を使用して設定する前に、値の型を事前に初期化することがあります心配します。
  • パフォーマンス:this()を使用すると、最初に構造体の値がデフォルトで初期化され、値が設定されることが心配です。不要な操作。それを避けるのがいいでしょう。
  • 清潔度:明らかに、:this()を使用すると、構造体がよりクリーンになります。なぜ私たちはそれを使いたくないのですか?

例:

public struct MyContainer 
{ 
    public MyContainer(int myValue) : this() 
    { 
     MyValue = myValue; 
    } 

    public int MyValue { get; private set; } 
} 


public struct MyContainer2 
{ 
    private readonly int _myValue; 

    public MyContainer2(int myValue) 
    { 
     _myValue = myValue; 
    } 

    public int MyValue 
    { 
     get { return _myValue; } 
    } 
} 

あなたは、パフォーマンスと行くための正しいルートで少ない.NETガベージを最適化しようとしている場合は?コンパイルされても違いはありますか?

データ処理のために何百万もの構造体を作成しているとき、私はこれを盲目的に受け入れたくありません。それらは短命のコンテナオブジェクトなので、ネットのゴミとパフォーマンスの問題です。

+2

私はリファクタリングを誤解していると思います:清潔さは 'this()'呼び出しではなく自動プロパティから来ています。 – dasblinkenlight

+1

@dasblinkenlight後者は前者を使うために必要な変更です。 – Servy

+0

メモリ内の場所をゼロに設定してすぐに別の場所に設定すると、ゴミが生成されません。この変更の結果として*できない新しいオブジェクトインスタンスを作成することで、ガベージが作成されます。 – Servy

答えて

1

私は「この()」初期化子と1なしで構造体の迅速なベンチマークを作成し、次のように:

struct Data 
    { 
     public Data(long big, long big2, int small) 
     { 
      big_data = big; 
      big_data2 = big2; 
      small_data = small; 
     } 

     public long big_data; 
     public long big_data2; 
     public int small_data; 
    } 

私は、各タイプの50億の構造体を初期化することにより、ベンチマーク。私は、デバッグモードで、 "this()"イニシャライザを持たない構造体テストがかなり高速であることを発見しました。リリースモードでは、ほぼ同等でした。私はリリースモードでは、 "this()"が最適化されており、デバッグでは "this()"が実行されており、structフィールドをデフォルトに初期化することも想定しています。

1

これは、自動実装されたプロパティと構造体に関する短い言語です。パフォーマンスに関しては

public struct MyContainer 
{ 
    public int MyValue { get; } 
    public MyContainer(int value) 
    { 
     MyValue = value; //readonly properties can be set in the constructor, similar to how readonly fields behave 
    } 
} 

:それはthisの明示的な呼び出しが不要であり、あなたも民間のセッターと離れて行うことができますC#6に固定されます。私は2つの間に顕著な違いがある場合、私は非常に驚くだろう(私は現在、生成されたILの違いを確認することはできません)。 (コメントごとに、回答の次のビットは無関係です。this()は追加の "ゴミ"を生成しません)また、オブジェクトがあなたのように短命であれば、私はごみのことをまったく心配しませんすべてがスタックに格納され、ヒープメモリには格納されません。

+0

'this'は暗黙的ですが、明示的にインクルードする必要はありませんが、同じことをやっています。その変更に問題がある場合は、何らかの理由で何も変更されません。 – Servy

+0

私は確かに余分なCPUのサイクルはほとんど測定できないと話す価値があります。しかし、値を設定する前にバッキングフィールドの初期化は私に不思議だったものです。私たちは技術的にそれを既定値型で事前に割り当てていますか?それから新しい値で設定しますか?操作は私が好奇心を持っているものです。 – TravisWhidden

+0

@Servyありがとう、私はそれを知らなかった。 – InBetween

関連する問題