7

私は私の質問を明確にしようとします:

Draw という関数があり (誰か (XNA) が 1 秒間に 60 回呼び出します)、描画するオブジェクトがたくさんあるので、次のコードを作成します。obj2.draw(); obj3.draw(); .... }

代わりに、Draw() によって発生するイベントを作成し、すべてのオブジェクトがイベントにサインアップすると、パフォーマンスに影響がありますか?

私が何を求めているのかはっきりしない場合: イベントにサインアップすることによる関数への呼び出しは、通常の呼び出しとは異なりますか?

4

2 に答える 2

6

パフォーマンスに関しては、 Jon Skeet の例は、デリゲートがパフォーマンスに大きなオーバーヘッドを追加せず、パフォーマンスを改善する可能性さえあることをかなり決定的に示していると思います。

イベント/デリゲートで考慮する必要がある要因の 1 つは、イベントをリッスンしているオブジェクトのフック解除を処理することです。そうしないと、参照カウントが適切にリセットされず、メモリ リークが発生する可能性があります。Dispose などで配線を解除できるように、匿名メソッドへの参照を保存する準備ができていない限り、匿名メソッドは避けてください。

于 2012-12-13T21:30:25.427 に答える
4

このildasmは、関数の直接呼び出しが「call method」コマンドで実行され、イベントを介した呼び出しが「callvirt delegatename::Invoke()」で実行されることを示しています。直接呼び出しの方が速いと思われるかもしれませんが、Invoke() とは何かを考えてみましょう。Invoke は、Delegate または MulticastDelegate クラスのメンバーではありません。コンパイラによって生成される特別なメソッドです

.method public hidebysig virtual instance void 
            Invoke(string s) runtime managed
{
}

このメソッドには実装が含まれていないため、奇妙に見えるかもしれません。しかし、「実行時」指定子に注意を払うと、魔法は消えてしまいます。「ランタイム」とは、実行時にコードが生成されることを意味し、ご存知のように、それは一度だけ発生します。したがって、理論的には、どちらも生産性の点で同じでなければなりません。

Jon Skeet のテストに関しては、私はそれを数回起動し、デリゲートの助けを借りて直接呼び出しと呼び出しを交換しましたが、デリゲートがパフォーマンスを向上させるという確認は得られませんでした。代議員が勝つこともあれば、直接電話が勝つこともありました。GC か .NET 内の何かがテストに影響を与えているか、Windows によってプロセスが切り替えられているためだと思います。

于 2012-12-13T22:04:54.277 に答える