http://blogs.wankuma.com/nakamura/archive/2008/11/25/162049.aspx
イベントを発生させるメソッドの実装(2)(Nakamura Blogより)
上記を読んで、面白いなー、と思って僕も試してみました。
public class Sample {
public event EventHandler<HelloEventArgs> Hello = delegate {};
protected virtual void OnHello(HelloEventArgs e) {
Hello(this, e); // null にならないからチェックが不要
}
}
確かに、インスタンス上から Hello を null する術がないということで、イベント発行時に null チェックが不要になる点では、すっきり書くことができますね。
また、毎回比較演算するよりは高速に処理できる筈・・・
でも、イベントの登録が 1 件増えるから、常に空の呼び出しが 1 件増えることとトレードオフな関係ですよね?
さて、どちらが高速なのでしょうか?
自分のメソッド内で、null 比較演算をする方が速いのか、イベントの空呼び出しによるオーバーヘッドの方が遅いのか?w
class TestClass {
static void Method() {
var t = new System.Diagnostics.Stopwatch();
ISample[] a = { new Sample1(), new Sample2() };
foreach(var i in Enumerable.Range(1, 5)) {
Console.WriteLine(i.ToString() + "回目のテスト-----");
foreach(var x in a) {
x.Hello += (sender, e) => {};
t.Reset();
t.Start();
foreach(var j in Enumerable.Range(0, 10000000)) x.Fire();
t.Stop();
Console.WriteLine(t.ElapsedTicks);
}
}
}
}
public interface ISample {
event EventHandler<EventArgs> Hello;
void Fire();
}
public class Sample1 : ISample {
public event EventHandler<EventArgs> Hello = delegate {};
public void Fire() {
Hello(this, EventArgs.Empty);
}
}
public class Sample2 : ISample {
public event EventHandler<EventArgs> Hello;
public void Fire() {
if (Hello != null) Hello(this, EventArgs.Empty);
}
}
1回目のテスト-----
18016811
11843868
2回目のテスト-----
19669451
18374921
3回目のテスト-----
22624583
21159129
4回目のテスト-----
25875112
24878342
5回目のテスト-----
29027337
27788239
null の比較演算を毎回行う方が僅かながら速いんですね。
まあ、殆ど気にならないくらいですけど。
どちらの書き方が良いのかは、ちょっと結論ができませんが、僕は今まで通り後者でいこうかなー