25

空のメソッド本体が与えられた場合、JIT は呼び出しを最適化します (C# コンパイラがそうしないことはわかっています)。どのように調べたらよいでしょうか?どのツールを使用し、どこを見ればよいですか?

必ず聞かれるのでメソッドが空の理由はプリプロセッサディレクティブです。


@Chris: 理にかなっていますが、メソッドへの呼び出しを最適化できます。したがって、メソッドは引き続き存在しますが、メソッドへの静的呼び出しは削除できます (または少なくともインライン化されます...)。

@ジョン:それは、言語コンパイラが何もしないことを教えてくれます。私がする必要があるのは、ngen を介して dll を実行し、アセンブリを確認することだと思います。

4

4 に答える 4

15

この章では、JIT 最適化について非常に適切に扱っています。このページで「メソッドが空です」を検索してください。記事の半分ほど下にあります -

http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx

どうやら空のメソッドは、実質的にコードがないものをインライン化することで最適化されます。

@クリス:メソッドはまだバイナリの一部であり、これらはJIT最適化であることを認識しています:-)。やや関連したメモとして、Scott Hanselman がリリース ビルド コール スタックのインライン化に関する非常に興味深い記事を書いています。

http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx

于 2008-08-14T23:43:29.903 に答える
13

あなたのコードは次のようなものだと思います:

void DoSomethingIfCompFlag() {
#if COMPILER_FLAG
    //your code
#endif
}

ただし、これは最適化されません。

partial void DoSomethingIfCompFlag();

#if COMPILER_FLAG
partial void DoSomethingIfCompFlag() {
    //your code
}
#endif

最初の空のメソッドは部分的であり、C#3コンパイラーがそれを最適化します。


ちなみに、これは基本的に部分的なメソッドの目的です。Microsoftは、デフォルトでは何も実行しないメソッドを呼び出す必要があるコードジェネレーターをLinqデザイナーに追加しました。

メソッドを強制的にオーバーロードするのではなく、パーシャルを使用できます。

このようにして、余分な空のメソッド呼び出しのオーバーヘッドを追加するのではなく、使用しない場合にパーシャルが完全に最適化され、パフォーマンスが失われることはありません。

于 2008-08-15T08:38:41.137 に答える
2

いいえ、空のメソッドが最適化されることはありません。以下にいくつかの理由を示します。

  • メソッドは、おそらく別のアセンブリ内の派生クラスから呼び出すことができます
  • このメソッドは、リフレクションを使用して呼び出すことができます (プライベートとマークされている場合でも)

編集:はい、その(優れた)コードプロジェクトのドキュメントを見ると、JITerは空のメソッドへの呼び出しを排除します。ただし、リストした理由により、メソッド自体は引き続きコンパイルされ、バイナリの一部になります。

于 2008-08-14T23:39:53.377 に答える
1

すべてが等しい場合、はい、最適化する必要があります。JIT は必要に応じて関数をインライン化し、空の関数よりも適切なものはほとんどありません :)

本当に確認したい場合は、空のメソッドを変更して例外をスローし、それに含まれるスタック トレースを出力します。

于 2008-08-14T23:41:30.080 に答える