Search code examples
c#performancestandards

Which has better performance, Action or Wiring to Event


Backstory:

So I'm trying to answer this question and I'm not sure how to go about it. I figured maybe someone on here has a good learning resource or possibly can give a clear answer.

In short, I'd like to know what is better on performance and what is better practice in standard C# OOP programming.

Question:

Is it better to, wire up to a event or is it better to let the consumer inject a action which can be called with results?

Example:

For example, I was building a search panel. My panel should be really good at searching but not really care how its results are used.

So my two options are, create a completed event in my view model and wire up to it from what ever cares about the results, or option number two, allow the caller to inject a callback action that will be invoked when the search is completed.

My initial thought is at a minimum they are equal because both the event and the action should just be a function reference pointer that is called. However, I can see bubble events being less performant.

Example Code:

public class Consumer{

    public Consumer(){
          StandardViewModel viewModel = new StandardViewModel(CompletedCallback);
          viewModel.customEvent += someEventHandler;
    }

    public void someEventHandler(Object sender, EventArgs args){
       // do something with results
    }
    public void CompletedCallback(List<string> results){
       // do something with results
    }

}


public class StandardViewModel{
    public event EventHandler customEvent;
    private Action<IEnumerable<string> _callback;
    public StandardViewModel(Action<IEnumerable<string>> callback){
           _callback = callback;
    }
}

Solution

  • The performance difference is tiny.

    1. Events are implemented by a compiler generated delegate field. When there is only one subscriber attached to the event (the usual case) that delegate is just like a manual delegate.
    2. Events usually have object sender, EventArgs args arguments (although this is optional). This can cause a tiny performance difference. There's also a tiny performance cost for attaching to the event compared to just passing a delegate to the constructor.
    3. Events do not "bubble" in .NET.

    These are very minor points.

    Which callback style should be used based on code quality concerns?

    1. When you take a callback the callback cannot be changed later. There will always be one subscriber to the event.
    2. You also can validate this delegate to be not null.
    3. You can also pass this delegate around to other code. This would not be possible with an event.
    4. In the event version you really are forced to not care how many subscribers there are. There could be zero or multiple. The subscriber list can change at any time. This is more flexible from that standpoint.

    Which style to use depends on how the class is supposed to be used. Here, I like the event style a bit better because you really do not case about the list of subscribers in any way.