理論的には、静的メソッドはインスタンスメソッドよりもわずかにパフォーマンスが優れているはずですが、他のすべての条件は同じです。これは、追加の非表示this
パラメーターがあるためです。
実際には、これはほとんど違いがないため、さまざまなコンパイラーの決定のノイズに隠されます。(したがって、2人が一方を他方よりも「証明」して、結果が一致しない可能性があります)。特に、this
は通常レジスタに渡され、そもそもそのレジスタにあることが多いためです。
この最後の点は、理論的には、オブジェクトをパラメーターとして受け取り、それを使用して何かを実行する静的メソッドが、同じオブジェクトのインスタンスとしての同等のものよりもわずかに劣ることを期待する必要があることを意味します。繰り返しになりますが、違いはごくわずかであるため、それを測定しようとすると、おそらく他のコンパイラーの決定を測定することになります。(特に、その参照が常にレジスターにある可能性が非常に高いため)。
実際のパフォーマンスの違いは、自然に静的である必要があることを行うためにオブジェクトをメモリ内に人工的に持っているか、または自然にインスタンスである必要があることを行うために複雑な方法でオブジェクトの受け渡しのチェーンを絡ませているかどうかにあります。
したがって、番号1の場合、状態を維持することが問題にならない場合は、静的であることが常に適切です。これは、静的であるためです。コンパイラの最適化をうまく処理するという全体的なルールはありますが、パフォーマンスの問題ではありません。奇妙な使用法よりも、通常の使用法で発生するケースを最適化する努力をした可能性が高くなります。
番号2。違いはありません。各メンバーには、メタデータの量、実際のDLLまたはEXEファイルに含まれるコードの量、および追加されるコードの量の両方に関して、クラスごとに一定のコストがかかります。これは、インスタンスでも静的でも同じです。
項目3についてthis
も同様this
です。ただし、注意:
this
パラメータは特定のレジスタに渡されます。同じクラス内のインスタンスメソッドを呼び出すとき、それはすでにそのレジスタにある可能性があり(それが隠されていて、何らかの理由でレジスタが使用されていない限り)、したがって、を設定するthis
必要があるものに設定するために必要なアクションはありません。これはある程度適用されます。たとえば、メソッドの最初の2つのパラメーターは、メソッドが行う呼び出しの最初の2つのパラメーターです。
this
nullでないことは明らかなので、場合によってはこれを使用して呼び出しを最適化することができます。
nullでないことは明らかなのでthis
、メソッド呼び出しを偽造するために生成されたコードは、とにかく必要になる可能性のあるnullチェックを省略できるため、インラインメソッド呼び出しが再び効率的になる可能性があります。
そうは言っても、ヌルチェックは安いです!
インスタンスメソッドではなく、オブジェクトに作用するジェネリック静的メソッドが、http://joeduffyblog.com/2011/10/23/on-generics-and-some-of-で説明されているコストの一部を削減できることは注目に値します。 the-associated-overheads/指定された静的が指定されたタイプに対して呼び出されない場合。彼が述べているように、「余談ですが、拡張メソッドは、一般的な抽象化をより有料にするための優れた方法であることがわかりました。」
ただし、これは、メソッドで使用される他のタイプのインスタンス化にのみ関連し、他の方法では存在しないことに注意してください。そのため、実際には多くの場合には適用されません(他のインスタンスメソッドがそのタイプを使用し、他のコードがそのタイプを使用しました)。
概要:
- ほとんどの場合、インスタンスと静的のパフォーマンスコストはごくわずかです。
- たとえば、静的なものを悪用したり、その逆を行ったりすると、一般的にどのようなコストが発生します。静的とインスタンスの間の決定の一部にしないと、正しい結果が得られる可能性が高くなります。
- 別のタイプの静的ジェネリックメソッドでは、インスタンスジェネリックメソッドよりも作成されるタイプが少なくなることがまれにあります。これにより、めったに使用されないようにすることで、わずかなメリットが得られる場合があります(「まれに」とは、アプリケーションの存続期間。呼び出される頻度ではありません)。彼がその記事で話していることを理解すると、とにかくほとんどの静的対インスタンスの決定とは100%無関係であることがわかります。編集:そして、それはほとんどの場合、jittedコードではなく、ngenでのみそのコストがかかります。
編集:ヌルチェックがどれほど安いかについてのメモ(私が上で主張した)。.NETのほとんどのnullチェックは、nullをまったくチェックしません。むしろ、nullが機能することを前提として実行を継続し、アクセス例外が発生すると、nullに変換されますNullReferenceException
。そのため、ほとんどの場合、C#コードがインスタンスメンバーにアクセスしているためにnullチェックが含まれる場合、成功した場合のコストは実際にはゼロです。例外は、いくつかのインライン呼び出しであり(インスタンスメンバーを呼び出したかのように動作したいため)、フィールドにヒットして同じ動作をトリガーするだけなので、非常に安価であり、とにかく省略されることがよくあります。 (たとえば、メソッドの最初のステップでフィールドにアクセスする必要がある場合)。