Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Would events with no listeners have a sizeable impact on performance?

Tags:

c#

.net

events

Considering the following basic event-related code inside a class:

public event EventHandler Updated;

public void OnUpdated() {
    if (Updated != null) Updated(sender: this, e: null)
}

If no one has subscribed to the Updated event, I would not like the fourth line to cause any significant performance drag (the idea is to let subscribers choose the most fine-grained events to subscribe to have only the minimal number of events fired and prevent a message queue overload).

Should I care and track the existence of subscribers (e.g. with if (Updated != null && OnUpdateSubscribed) Updated(sender: this, e: null) or trust the compiler/runtime?

like image 990
Erwin Mayer Avatar asked Dec 09 '25 21:12

Erwin Mayer


1 Answers

The check OnUpdate != null defines an event being subscribed / unsubscribed. In fact, there is no real difference between a boolean check and a null check, because ultimately both of them are just a "load field", "branch if false" - because a null reference counts as "false" as far as logic checks are concerned.

My only suggestion would be: store it in a local variable, to prevent a (pretty unlikely, but possible) race condition:

var snapshot = Updated;
if(snapshot != null) snapshot(this, EventArgs.Empty);

So: no, basically: there is no overhead of this.

Example:

public event EventHandler SomeEvent;
protected virtual void OnSomeEvent()
{
    var snapshot = SomeEvent;
    if (snapshot != null) snapshot(this, EventArgs.Empty);
}

Compiles to (comments are mine):

.method family hidebysig newslot virtual instance void OnSomeEvent() cil managed
{
    .maxstack 3
    .locals init (
        [0] class [mscorlib]System.EventHandler snapshot)

    // var snapshot = SomeEvent
    L_0000: ldarg.0 
    L_0001: ldfld class [mscorlib]System.EventHandler Foo::SomeEvent
    L_0006: stloc.0

    // if(snapshot == null) goto L_0016;
    L_0007: ldloc.0 
    L_0008: brfalse.s L_0016

    // snapshot(this, EventArgs.Empty);
    L_000a: ldloc.0 
    L_000b: ldarg.0 
    L_000c: ldsfld class [mscorlib]System.EventArgs [mscorlib]System.EventArgs::Empty
    L_0011: callvirt instance void [mscorlib]System.EventHandler::Invoke(object, class [mscorlib]System.EventArgs)

    // L_0016: return;
    L_0016: ret 
}
like image 96
Marc Gravell Avatar answered Dec 12 '25 11:12

Marc Gravell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!