views:

135

answers:

3

We were having a discussion at the office on how to solve a particular problem and using an event was raised (no pun intended). The response was negative citing misuse and that they can be expensive.

I understand the concerns behind misuse and I know that they are just a special multicast delegate but given a scenario where there is at most one listener why would using an event over a method call be considered "expensive"?

EDIT

Just to be clear this is not about any particular implementation this is a more general question about the cost of using an event over a method call.

+10  A: 

In .NET 2.0 calling a delegate is just as fast as an interface method call. They even seem to be a bit faster.

But even if the overhead were 10x higher, I doubt delegate calls would ever be the speed bottleneck in your application. Use a profiler if you want to find the real bottlenecks.

edit in response to the claim that events are slower than delegates: In fact, events are delegates. This code shows that their performance is identical, at least on my machine.

Wim Coenen
There is no specific application as such. The discussion where more rhetorical than anything else but your link was very useful, thanks.
Bronumski
Unfortunately the link you provided was using delegates and not events. After amending the code I got similar results to Philip.
Bronumski
Your link is still useful for anyone wanting to see the comparison using delegates though.
Bronumski
@Bronumski: events *are* delegates. Declaring an event is almost identical to declaring a field holding a delegate. See here for differences introduced by using the `event` keyword: http://blog.monstuff.com/archives/000040.html
Wim Coenen
@Wim: I appreciate that events are multicast delegates with the signature (object, EventArgs). Using the code in your link I added an additional test using an event and the results were twice as slow. It could have been speed up using the EventArgs.Empty static rather than creating a new EventArg for each call but that would not have modelled how the event would have been used.
Bronumski
@Bronumski: I have linked to some test code which shows that the performance of events and delegates is identical.
Wim Coenen
I agree with what your are saying that calling a delegate with the same signature as an event (object o, EventArgs e) is exactly the same. My point is that if you want to call a parameterless method be it directly or via a delegate you are not going impose the above signature on that method if you don't have to. Like wise if you want to pass the method a parameter you are not necessarily going to wrap that object up in another object (EventArgs). Again your direct comparison is correct but being practical you have to accept the overhead of creating an EventArg object if you want to use events.
Bronumski
@Bronumski: You can declare events as a `System.Action` (e.g. `public event Action<int> SomeEvent`) if you want to avoid the overhead of instantiating an EventArgs object. I've updated the test code to demonstrate this.
Wim Coenen
Fair point, something I hadn't even considered, I was using the generic EventHandler. It does show that the event is a little slower but not to the extremes I was looking at. Thanks for showing me that.
Bronumski
That was interesting. I changed the IHandler, Handler and Raiser to be public and got better results: BEFORE Delegate = .0960055, Event = .1200068, Interface = .1100063 AFTER Delegate = .1240071, Event = .0960055, Interface = .1100062 The results for the interface and event were reversed.
Bronumski
@Wim I posted my code in my answer - I want to note that with both our codes I get pretty different results (not just added time, but relative costs!) through debug/release or debugger attached/not attached.
Philip Rieck
+2  A: 

Performance is definitely not something you should concern yourself about. You're talking about nanoseconds here. If you have just one listener, there is no difference at all.

I would simply consider what makes more sense in your application, using events or calling a method and choose the best option. The main difference being that an object A generating events doesn't have to know its listener(s). The same object A calling a method has to know the instance to call it from. Where do you want to put the dependency?

Ronald Wildenberg
I agree with your statement and the whole purpose of the discussion was to agree on a pattern that was logical and clear. My question here was merely to get some clarity on the statement that "Events are expensive".
Bronumski
+8  A: 

Test it in your scenario - I would imagine that many, many factors can affect this, especially when we're talking something with such a low relative cost as a method/delegate call.

A quick and simple test with a release build not under a debugger, compiled under 4.0 as "any cpu", and running on 64-bit windows 7:

Another Edit: Oops Here's a better result. See the code for how it's working

10000000 direct reference calls     :   0.011 s
10000000 calls through an interface :   0.037 s
10000000 invocations of an event    :   0.067 s
10000000 calls through Action<int>  :   0.035 s

So in a straight "do nothing test" with ten million calls, an event adds .474 sec [edit, only .026 now on a much better machine, still roughly double however]

I would worry more about correctness of design than half a second every 10 million calls, unless you are expecting to do that many calls in short periods of time (in which case perhaps there is a more fundamental design issue).

Philip Rieck
The question wasn't about any design in particular it was more about why "Events would be considered expensive". There is no particular test scenario but thanks for doing your test and sharing the results, it answers the question and should be helpful to others.
Bronumski