をカプセル化する場合、私は、このようなコードの部分を持っているを削除しますか?または、評価が維持され、処理時間がかかりますか?C#コンパイラは、それがdebug.writeline
答えて
はい、これは、少なくともDebug
の呼び出しであります。 JITコンパイラでもif
の評価が削除されても、私はここには見えませんが、等式には副作用がないため、このように思っています。
ただし、評価を削除するためにJITコンパイラに依存しないDebug.WriteLineIf
を呼び出すことにより、安全性を保つ方がよい場合があります。
Debug.WriteLine
を削除するためのコンパイラの証明を完全にするため。
リリースビルドでコード:デバッグビルドで
.method public hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 17 (0x11)
.maxstack 8
IL_0000: call string [mscorlib]System.Console::ReadLine()
IL_0005: ldstr "Ok"
IL_000a: call bool [mscorlib]System.String::op_Inequality(string,
string)
IL_000f: pop
IL_0010: ret
} // end of method Program::Main
コード:
.method public hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 42 (0x2a)
.maxstack 2
.locals init ([0] string state,
[1] bool V_1)
IL_0000: nop
IL_0001: call string [mscorlib]System.Console::ReadLine()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr "Ok"
IL_000d: call bool [mscorlib]System.String::op_Inequality(string,
string)
IL_0012: stloc.1
IL_0013: ldloc.1
IL_0014: brfalse.s IL_0029
IL_0016: nop
IL_0017: ldstr "Error occured: {0}"
IL_001c: ldloc.0
IL_001d: call string [mscorlib]System.String::Format(string,
object)
IL_0022: call void [System]System.Diagnostics.Debug::WriteLine(string)
IL_0027: nop
IL_0028: nop
IL_0029: ret
} // end of method Program::Main
あなたはリリースモードでデバッグモードがないDebug.WriteLine
への呼び出しを、持っていない見たよう
MSDN's page on the Debug class:
からデバッグ情報を印刷し、アサーションを使用してロジックをチェックする
Debug
クラスのメソッドを使用する場合は、あなたの船積みの製品の性能やコードサイズに影響を与えることなく、あなたのコードをより堅牢にすることができます。...
ConditionalAttribute
属性はDebug
の方法に適用されます。ConditionalAttribute
をサポートするコンパイラは、 "DEBUG"が条件付きコンパイルシンボルとして定義されていない限り、これらのメソッドの呼び出しを無視します。
ご覧のとおり、コンパイラは、非デバッグビルドのメンバーDebug
への呼び出しをすべて省略します。ただし、プログラムがif文をチェックするのを止めることはありません。あなたはコンパイラが同様にif文を無視したい場合は、そのようにブロック全体を囲むpreprocessor directiveを使用することができます。
#if DEBUG
if (state != "Ok")
{
Debug.WriteLine($"Error occured: {state}, {moreInfo}");
}
#endif
C#コンパイラがDebug
呼び出しを削除するために、言語仕様によって必要とされるとその議論の評価。
.NET JITが洗練されたJITであった場合、文字列メソッド呼び出しが副作用ではなく、削除できると判断します。 .NET JITはあまり洗練されていないので、実際にはそのメソッドを呼び出す機会があります。確認してみましょう。
デバッガが最適化を抑制することなく、プログラムをリリースモードでコンパイルし、コンパイルして、4.6.2でx64として実行します。これは側 - かもしれないので、私はスペックの許可は、これを最適化するかどうかわからないんだけど
:
static void Main()
{
var state = GetState();
if (state != "Ok")
{
Debug.WriteLine(state);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static string GetState()
{
return "x";
}
C#コンパイラは、完全な文字列の不平等のコールを残しましたエフェクト方法。コンパイラがそのことについてどのように仮定できるかは不明です。
私たちの幻想的なJITも呼び出しを削除しませんでした:
(1)GetState()
で、(2)string.!=
です。
使用Debug.WriteLineIf
ので:条件付き属性で飾られた方法は、条件付きメソッドです
17.4.2.1条件付きメソッド 。 Conditional属性は、条件付きコンパイルシンボルをテストして条件を示します。条件付きメソッドへの呼び出しは、このシンボルが呼び出しの時点で定義されているかどうかに応じてインクルードまたは省略されます。シンボルが定義されている場合は、呼び出しが含まれます。それ以外の場合、呼び出し(受信者の評価と呼び出しのパラメーターを含む)は省略されます。
「Debug.X」呼び出しを削除する必要があることを仕様のどこで参照できますか? –
@JeroenVannevel私はそれを追加しました。 – usr
- 1. デバッグ中にDebug.WriteLineがスキップされる
- 2. C#のDebug.WriteLine() - 何をしますか?
- 3. Debug.WriteLineはVisual Studioで誤動作します。それを修正するには?
- 4. は、C++コンパイラ
- 5. log4net Logging Debug.WriteLine and Console.WriteLine
- 6. コンパイラが割り当てられているが、その値は
- 7. CコンパイラでC
- 8. Cは、それがバイナリ
- 9. Javaバッファストラテジ:コンパイラがそれを好きではない
- 10. は出力できませんDebug.WriteLine(「テスト」)
- 11. なぜC#コンパイラは、InvalidCastExceptionがに
- 12. Opensource C/C++逆コンパイラ
- 13. C++ {}それは
- 14. は...それC
- 15. それはC#
- 16. C++ - それは
- 17. C++コンパイラのエラー
- 18. C++コンパイラstable_partitionエラー
- 19. static_assertインテルC++コンパイラ
- 20. コンパイラとC++
- 21. CodeDomコンパイラfor C#
- 22. CygwinのC++コンパイラ
- 23. C++コンパイラとプリプロセッサ
- 24. C#Sassコンパイラ
- 25. C#コンパイラはオープンソースですか?
- 26. GLIB:のconfigure:エラー:Cコンパイラは
- 27. CコンパイラはSUA/Interixの
- 28. gcc CコンパイラはC言語で書かれていますか?
- 29. GNU C/C++コンパイラには検索順序が含まれています
- 30. Microsoft Cコンパイラ.ECと.Cソースファイル
'Debug.WriteLineIf'メソッドを使用します。 –
注:単一のC#コンパイラはありません。いくつかのC#コンパイラがあり、それぞれが多くのバージョンでリリースされています。 C#仕様には(もしあれば)義務的な最適化がほとんどありませんので、特定のコンパイラと特定のバージョンに関してだけ答えが得られます。 –