2

次のコードがあります。

var ad = product.AttributesDictionary;
var ddl = product.DetailedDescriptionList;
var rdl = product.RelatedProductList;

C#/JIT コンパイラが多くの最適化を実行できることを読みました。変数は代入後に使用されないため。C#/JIT コンパイラが最適化のためにこれらの行を省略してしまうのではないかと心配しています。

この行を削除するように言わないでください。

更新:誰も私の言いたいことを理解できないと思います。私の質問は、プロパティを変数に割り当ててからこの変数を使用しない場合、C#/JIT コンパイラはこのコードを省略しますか?

4

5 に答える 5

4

(これは C# コンパイラに固有のものではなく、単なる一般的な観察です)

変数へのプロパティの割り当てには、実際には次の 2 つの部分があります。

  1. プロパティの get メソッドの実行
  2. メソッドの戻り値を変数に代入します。

最初の部分は他のメソッドと同じくらい複雑になる可能性があり、多くの副作用を伴う可能性があるため、コンパイラはそれを最適化することはありません。

割り当て後に変数が使用されていない場合、コンパイラが積極的に最適化を行っている場合、2 番目の部分を最適化できます。


ただし、予測しにくい別の種類のオプティマイザがあります。それは、そのコードを次に見る開発者です。

これらの行は何もしていないように見えるので、次にそれらを見た人が (ほとんどの開発者がそうであるように) 余分なコードを嫌う衒学者である場合、それらの行は一目瞭然で削除される可能性があります。

これらの行で達成しようとしていることを達成するための、より良い (より明確な) 方法を見つけるようにしてください。

于 2013-09-17T11:40:55.613 に答える
1

さて、仕様がこれについて何を言っているか見てみましょう:

セクション 3.10: 実行順序

C# プログラムの実行は、実行中の各スレッドの副作用が重要な実行ポイントで保持されるように進行します。副作用は、揮発性フィールドの読み取りまたは書き込み、非揮発性変数への書き込み、外部リソースへの書き込み、および例外のスローとして定義されます。

[..]

さらに、実行環境は、式の値が使用されておらず、必要な副作用 (メソッドの呼び出しまたは volatile フィールドへのアクセスによるものを含む) が生成されていないと推測できる場合、式の一部を評価する必要はありません。

コードが例外をスローする可能性は明らかであるため、アクセスが最適化されていない場合、コンパイラのバグになります。

したがって、このコードは技術的に安全です。アクセサーから例外をスローすることは、法律の文言だけでなく、その精神とも一致します。つまり、アクセサーはメソッドであり、メソッドは詳細に応じて例外をスローすることが期待できます。

ただし、このコードの人間に面した側では、見栄えがよくありません。何かをチェックしたいという合理的な期待がある場合は、コードでこれを有効にする必要があります。

obj.TrySomething()

これを行う必要はありません

try { obj.DoSomething(); }
catch (SomeException e) { ... }
于 2013-09-17T11:45:33.343 に答える
1

ダミー呼び出しでフライウェイトキャッシュを強制的に初期化しようとしている場合は、コンパイラがその行を省略しないと私が信じているToString()ように、試すことができます。キャッシュの動作に応じて、 null かproduct.AttributesDictionary.ToString();どうかを確認する必要がある場合があります。product.AttributesDictionary

于 2013-09-17T11:41:49.163 に答える
1

このコードをアセンブリ (DLL または EXE) にコンパイルし、ILDASMを使用してプレーン テキストの IL に変換することで、答えを見つけることができます。

JIT は IL を x86/x64 マシン コードに変換するため、実行時に何が起こるかはまだ正確にはわかりません。しかし、Visual Studio デバッガーはその逆アセンブルを示し、さらに掘り下げることができます。

于 2013-09-17T11:46:01.307 に答える