Form_Load vs Constructor

  • Thread starter Thread starter Smithers
  • Start date Start date
Jack said:
Events are there so other objects can be notified of things happening.

According to Michael, no other objects will subscribe to the event.
Thus my question.
The OnXXX methods are there so subclasses can be notified of things
happening more efficiently than by using an event.

I doubt that efficiency is even a secondary reason for the methods
existing. Certainly the primary reason has more to do with the overall
design of the .NET classes, than any efficiency concern. As has been
mentioned elsewhere (in this thread, even), providing a virtual method
for derived classes to override provides enhanced control over the
sequencing of raising of events, as well as whether events are raised at
all.

The overridable methods are more about the capabilities of the
architecture than of some efficiency issue.

Pete
 
Peter Duniho said:
Right back at you.

I was writing about the two negative outcomes to failing to call the base
class: one is that the OnLoad method itself does not get called; the other
is that failing to call the base OnLoad also results in a failure for the
event to be raised.

Somehow, you seem to have missed this point.

I have not missed this point at all. The OnLoad in the base class does
nothing but raise the event. Certainly I have missed calling OnLoad many
many times and had no side effects.
Yes, I can see that you are convinced. If you would spend a little more
time reading my post rather than just assuming I'm blowing you off, you
might not be so convinced.

So far you have expressed confusion at most of what I have posted.
This originally came up in the context of you claiming that even though
the programming errors involved are "possibly both equally likely", that
it was the case that "The event is a problem in 100% of cases where the
override might be a small percentage".

You have yet to post something that explains exactly what percentages
you're talking about, never mind explains the math involved.

It's fairly simple. Missing the this.Load += whatever is *always* a problem,
ie 100%. Failing to call OnLoad is not going to always going to be a
problem, ie a number less the 100%.
I checked Google, and it had nothing to say on the topic that supports
your claim.

Sounds like the classic "I haven't listened to a single complaint" :-)
Google would most definately have information on this.
If you want to make a claim, back it up. If you can't back it up, then
you have no business making the claim. And no, saying "look it up" is not
backing up the claim. If you yourself cannot readily provide the
references to justify the claim, then you yourself do not have the
first-hand knowledge required to legitimately make the claim.

My claim is fairly well known and accepted. If you wish to challenge the
fact that the world is not flat then you need to provide information. So far
I have provided the fact that at least 1 additional object (the delegate) is
required which contains a collection of listeners. This indicates that there
is at least some additional overhead, it's up to you to disprove this.

Michael
 
Peter Duniho said:
According to Michael, no other objects will subscribe to the event. Thus
my question.

You claim you're reading my posts but still don't get what I'm saying. I'm
not saying no other object will ever subscribe to the event. I'll repeat
again - what I did say was it was LESS LIKELY to the event would be used in
this case given the override was being used.
I doubt that efficiency is even a secondary reason for the methods
existing. Certainly the primary reason has more to do with the overall
design of the .NET classes, than any efficiency concern. As has been
mentioned elsewhere (in this thread, even), providing a virtual method for
derived classes to override provides enhanced control over the sequencing
of raising of events, as well as whether events are raised at all.

The overridable methods are more about the capabilities of the
architecture than of some efficiency issue.

That's probably true, although given they are more efficient they may as
well be used.

Michael
 
Peter said:
I checked Google, and it had nothing to say on the topic that supports
your claim.

And, by the way, since something as easily tested as this is such a dumb
thing to even get stuck on, I wrote a small console application to test
the difference (code copied below).

The overall performance varies quite a bit depending on context: the
first time the program runs in a given context, the two methods are
practically the same, but subsequent executions show a small difference.
The virtual method implementation is only faster in one scenario:
running outside the debugger, with the debug (non-optimized) build.

The event-based implementation is faster while running in the debugger,
and more importantly is _also_ faster in the optimized build running
from the command prompt.

Of course, both indirect calls are noticeably slower than simply calling
a method directly. But even there, the difference is small. Also, I
found that code order significantly affects the performance, much more
so than the implementation details. For example, I was able to get the
event-based implementation to be MUCH faster, simply by running it after
the other two implementations. The virtual method implementation did
not enjoy a similar boost by putting it at the end.

I ran a version of the code that repeated the event and virtual-method
implementations after the direct call, and the difference was even
greater. Both the event-based and virtual method implementations
enjoyed a faster run, but the virtual-method implementation only jumped
by about 25%, while the event-based implementation jumped 75%.

The most disparate case using the code posted below was a sequence of
trials running from the command-prompt, with the optimized build, and in
that case, for a five-second test run for each implementation, I got
about 9 million iterations with the virtual method, about 10 million
iterations with the event-based implementation, and about 13 million
iterations calling the method directly.

Note that this was an unusual sequence. I refactored the code so that
the TimeSpan passed to each method was initialized once in a local
variable, rather than once per call, and that brought the iteration
count for each method closer to the average for some reason (probably a
cache issue, since the TimeSpan was of course initialized outside of any
of the code actually measuring performance). This refactored code is
what I posted here.

Other than the ordering effect I noted three paragraphs back, the actual
iteration count for most of the trials was VERY close for all
mechanisms; almost always, it came in right around 11 million iterations
in 5 seconds. The only time I was able to produce a significant
difference between the mechanisms, regardless of the type of build and
context for running, was the dramatic improvement the event-based
mechanism got the second time it was run within the same execution of
the test app, and in that case the event-based mechanism was nearly
double the performance of any other method.

Frankly, while the numbers directly contradict your claim that using
events is slower, it's still my opinion that the performance difference
is not really worth worrying about at all. If you are doing so little
in your methods that the roughly 10% difference between virtual methods
and events is important, what you really need to do is change your code
so it doesn't spend so much of its time just dealing with the overhead
of calling functions.

But if you really believe that sort of performance difference is worth
worrying about and don't want to fix the code so that calling overhead
isn't significant, you're better off using events than virtual methods.

Pete


Here's the code:

using System;

namespace TestVirtualEvent
{
class Program
{
class TestClass
{
long _iterations;

public long RunVirtual(TimeSpan tsDuration)
{
DateTime dtEnd;

_iterations = 0;

dtEnd = DateTime.Now + tsDuration;
while (DateTime.Now < dtEnd)
{
_TestVirtual();
}

return _iterations;
}

public long RunEvent(TimeSpan tsDuration)
{
DateTime dtEnd;

_iterations = 0;
_TestEvent += _TestEventHandler;

dtEnd = DateTime.Now + tsDuration;
while (DateTime.Now < dtEnd)
{
_TestEvent();
}

return _iterations;
}

public long RunDirect(TimeSpan tsDuration)
{
DateTime dtEnd;

_iterations = 0;

dtEnd = DateTime.Now + tsDuration;
while (DateTime.Now < dtEnd)
{
_TestDirect();
}

return _iterations;
}

delegate void VoidDelegate();
event VoidDelegate _TestEvent;

protected virtual void _TestVirtual()
{
_iterations++;
}

void _TestEventHandler()
{
_iterations++;
}

void _TestDirect()
{
_iterations++;
}
}

static void Main(string[] args)
{
TestClass test = new TestClass();
TimeSpan ts = new TimeSpan(0, 0, 5);

Console.WriteLine("virtual: {0} iterations",
test.RunVirtual(ts));
Console.WriteLine("event: {0} iterations",
test.RunEvent(ts));
Console.WriteLine("direct: {0} iterations",
test.RunDirect(ts));
Console.ReadLine();
}
}
}
 
Michael said:
[...]
I have provided the fact that at least 1 additional object (the delegate) is
required which contains a collection of listeners. This indicates that there
is at least some additional overhead, it's up to you to disprove this.

Ignoring for a moment that your analysis doesn't say anything about the
actual cost of executing the event or method, I will simply say this: I
have disproved this. See the other article I just posted.

Pete
 
Michael said:
I have not missed this point at all.

Yes, you have. You continue to.
The OnLoad in the base class does
nothing but raise the event.

The "base class" in my post is YOUR class. Presumably if you took the
time to write an override method for OnLoad, it does more than just
raise the event.
So far you have expressed confusion at most of what I have posted.

If by "confusion" you mean I have posted comments indicating that what
you've posted doesn't make any sense, yes. I'd have to agree with your
statement here.
It's fairly simple. Missing the this.Load += whatever is *always* a problem,
ie 100%. Failing to call OnLoad is not going to always going to be a
problem, ie a number less the 100%.

Failing to call OnLoad in a class derived from your implementation that
includes an OnLoad override IS _always_ going to be a problem. 100% of
the time.

If you want to restrict the scenario to only your specific
implementation, then I'd say you are no more or less likely to forget to
subscribe your event than you are to forget to write the OnLoad
override. The fact is, both errors are basically non-existent. Your
"math" is contrived.
Sounds like the classic "I haven't listened to a single complaint" :-)
Google would most definately have information on this.

Feel free to post a Google search that would easily turn up the
information you claim is easily found there. Be sure to point out the
URLs that the search returns that actually provide the information you
claim they provide.

I am happy to acknowledge that I've somehow missed something. But so
far, all you've done is express an inability to actually point to
something I've missed. That's a pretty lame debating tactic, and one
that's sure to fail you every time.

If I'm wrong, show me. If you can't show me, well..."put up or shut up"
seems to apply here.

Pete
 
Peter Duniho said:
And, by the way, since something as easily tested as this is such a dumb
thing to even get stuck on, I wrote a small console application to test
the difference (code copied below).

This test is hardly a complete at all. Do you think the OnLoad method of
form will simply raise the event without even checking whether it is null or
not? Let alone all the other potential code it could have?

Also, efficiency is not just the speed at which the event is called, in fact
this is likely to be the least important factor in the majority of cases.
The amount of objects and references it creates is going to be more
important in 99%+ of cases.

Michael
 
Peter Duniho said:
The "base class" in my post is YOUR class. Presumably if you took the
time to write an override method for OnLoad, it does more than just raise
the event.

In many cases it does not.
If by "confusion" you mean I have posted comments indicating that what
you've posted doesn't make any sense, yes. I'd have to agree with your
statement here.

No, you have expressed genuine confusion. I have had to explain a very
simple point over and over and I still don't think you get it.
Failing to call OnLoad in a class derived from your implementation that
includes an OnLoad override IS _always_ going to be a problem. 100% of
the time.

No way. There are most definately cases where the OnLoad in the base class
will simply raise an event that is not used. Hence the number MUST be less
than 100%.
If you want to restrict the scenario to only your specific implementation,
then I'd say you are no more or less likely to forget to subscribe your
event than you are to forget to write the OnLoad override. The fact is,
both errors are basically non-existent. Your "math" is contrived.

Largely this will apply to forms. It applies to controls or other objects
much less often.
Feel free to post a Google search that would easily turn up the
information you claim is easily found there. Be sure to point out the
URLs that the search returns that actually provide the information you
claim they provide.

No. This is something I have read many times and is fairly widely accepted.
I'm not going to waste my time proving the sky is blue.
I am happy to acknowledge that I've somehow missed something. But so far,
all you've done is express an inability to actually point to something
I've missed. That's a pretty lame debating tactic, and one that's sure to
fail you every time.

If I'm wrong, show me. If you can't show me, well..."put up or shut up"
seems to apply here.

Whatever. Clearly you spent a reasonable amount of time benchmarking events
to prove nothing. I'm just not as invested in this thread as you.

Michael
 
Michael said:
In many cases it does not.

Please post a real-world example of an implementation of a class that
overrides OnLoad and yet does nothing but raise the event. By
"real-world", I mean an implementation that clearly needs to override
OnLoad, and would be seen in an actual program.
[...]
If I'm wrong, show me. If you can't show me, well..."put up or shut up"
seems to apply here.

Whatever. Clearly you spent a reasonable amount of time benchmarking events
to prove nothing. I'm just not as invested in this thread as you.

Yes, I can understand how when you cannot support your claims, being
"not as invested" would be a desirable position to be in.

I accept your decision to "shut up" rather than "put up". Thank you.

Pete
 
Michael said:
This test is hardly a complete at all. Do you think the OnLoad method of
form will simply raise the event without even checking whether it is null or
not? Let alone all the other potential code it could have?

The question here is whether calling an event is more costly than
calling a virtual method. My code tests that.

Please feel free to post an alternative benchmark that demonstrates your
point.
Also, efficiency is not just the speed at which the event is called, in fact
this is likely to be the least important factor in the majority of cases.
The amount of objects and references it creates is going to be more
important in 99%+ of cases.

I agree. And since those things are identical regardless of whether you
use a virtual method or an event, _whatever_ performance difference
exists between using a virtual method or an event is EVEN LESS. Which
is, by the way, what I've been saying all along.

You are the one claiming that there is a significant difference between
calling a virtual method and using an event. All you're doing now is
arguing against your own claim.

Pete
 
Peter Duniho said:
Please post a real-world example of an implementation of a class that
overrides OnLoad and yet does nothing but raise the event. By
"real-world", I mean an implementation that clearly needs to override
OnLoad, and would be seen in an actual program.

I'm talking about the *base* class.
Yes, I can understand how when you cannot support your claims, being "not
as invested" would be a desirable position to be in.

I accept your decision to "shut up" rather than "put up". Thank you.

Again mate, if you want to question the generally accepted norm then go
ahead and provide some evidence.

Michael
 
Peter Duniho said:
The question here is whether calling an event is more costly than calling
a virtual method. My code tests that.

No, the question is whether attaching to an event, detaching etc etc and
then calling it is more expensive. Most of us look at the entire picture.
Please feel free to post an alternative benchmark that demonstrates your
point.

Could not be bothered but I have no doubt the event would be less efficent
overall.
I agree. And since those things are identical regardless of whether you
use a virtual method or an event, _whatever_ performance difference exists
between using a virtual method or an event is EVEN LESS. Which is, by the
way, what I've been saying all along.

You are the one claiming that there is a significant difference between
calling a virtual method and using an event. All you're doing now is
arguing against your own claim.

Actually I never said there was a significant difference, in fact I claimed
there was a small difference. However given there is a small difference it's
better to use the override as it is more efficient.

Michael
 
Michael said:
I'm talking about the *base* class.

I am too.

The difference being that I am talking about the base class, regardless
of whether it is one that derives from an existing .NET class or not,
while you have chosen to arbitrarily restrict your consideration to a
specific base class (I assume the Control class, since you are so
focused on the behavior of that class's implementation of OnLoad, but
you haven't been explicit so I can't be sure).

Make no mistake: your restriction _is_ arbitrary, and focusing only on
one specific base class completely misses the real issues regarding how
overriding OnLoad could fail.
Again mate, if you want to question the generally accepted norm then go
ahead and provide some evidence.

You've yet to support your assertion that your position _is_ the
"generally accepted norm". So frankly, while I certainly am in the
habit of questioning "the generally accepted norm" when that "norm"
makes no sense, there's no indication at all that I'm doing so in this case.

Pete
 
Michael said:
No, the question is whether attaching to an event, detaching etc etc and
then calling it is more expensive. Most of us look at the entire picture.

Whatever. Post your code then. Prove me wrong. I don't actually mind
being wrong, if someone actually _shows_ me to be wrong. But just
saying I'm wrong and then refusing to justify that claim is stupid. You
might as well say "I just want to disagree for the heck of it" and "I
don't really care what the truth is".
Could not be bothered but I have no doubt the event would be less efficent
overall.

You can't be bothered to do a simple test, and yet you have no doubt?
You don't see that attitude as somehow arrogant? You are so certain of
your own prejudices that you cannot be bothered to test them at all?
Actually I never said there was a significant difference, in fact I claimed
there was a small difference. However given there is a small difference it's
better to use the override as it is more efficient.

There is not enough of an efficiency difference to justify using the
difference in the design decision at all. Furthermore, my own test
shows that events are actually more efficient, so if you do insist on
using efficiency as an input for the design decision, you should choose
events.

Pete
 
Peter Duniho said:
I am too.

The difference being that I am talking about the base class, regardless of
whether it is one that derives from an existing .NET class or not, while
you have chosen to arbitrarily restrict your consideration to a specific
base class (I assume the Control class, since you are so focused on the
behavior of that class's implementation of OnLoad, but you haven't been
explicit so I can't be sure).

Make no mistake: your restriction _is_ arbitrary, and focusing only on one
specific base class completely misses the real issues regarding how
overriding OnLoad could fail.

Hang on a sec there. In any class where I have an override that corresponds
to an event it's unlikely the code will do anything except raise the event.
Remember we are talking about an OnWhatever function and a Whatever event.
It's *extremely* likely the OnWhatever function will do nothing except raise
the event.

Beside which the Form is going to be what this applies to in 99% of cases.
You've yet to support your assertion that your position _is_ the
"generally accepted norm". So frankly, while I certainly am in the habit
of questioning "the generally accepted norm" when that "norm" makes no
sense, there's no indication at all that I'm doing so in this case.

I really don't care.

Michael
 
Peter Duniho said:
Whatever. Post your code then. Prove me wrong. I don't actually mind
being wrong, if someone actually _shows_ me to be wrong. But just saying
I'm wrong and then refusing to justify that claim is stupid. You might as
well say "I just want to disagree for the heck of it" and "I don't really
care what the truth is".

As I said, I cannot be bothered. I really don't care enough about your
misunderstanding to give you the educating you need.
You can't be bothered to do a simple test, and yet you have no doubt? You
don't see that attitude as somehow arrogant? You are so certain of your
own prejudices that you cannot be bothered to test them at all?

I don't really care how it comes across, I just could not be bothered.
There is not enough of an efficiency difference to justify using the
difference in the design decision at all. Furthermore, my own test shows
that events are actually more efficient, so if you do insist on using
efficiency as an input for the design decision, you should choose events.

Your tests were clearly shown to be flawed. While the efficiency might be
minor a minor difference is enough for me. In cases like this were it's
pretty much the same either way a small difference tips the scales.

Michael
 
I really don't care.


The intent behind my OP [of this thread] is to learn best practices and
such. So I'm very much interested in learning about accepted norms that may
be floating around - of which I may be unaware. If you have "checked out" of
caring about this thread and don't want to post specific links, can you at
least reply with some key words or phrases that I can google to discover
this norm of which you write?

Thanks
 
Michael said:
As I said, I cannot be bothered. I really don't care enough about your
misunderstanding to give you the educating you need.

You fail to comprehend that this is not just about "my
misunderstanding". It is also about "your misunderstanding". So far,
the only thing objective posted to this thread has been by me, showing
your own misunderstanding.

This isn't about "the educating I need". This is about getting the
facts right. If you can't be bothered, what you can't be bothered with
is getting the facts right.

Your own arrogance, insisting that you are right without be able to be
bothered to investigate whether that's true or not, is getting in your
own way of learning something.
[...]
Your tests were clearly shown to be flawed.

By whom? I must have missed where that happened. Please show me where
my tests "were clearly shown to be flawed". All you've posted is
conjecture. You certainly have suggested my test was flawed, but you've
done absolutely nothing to _show_ they are flawed, never mind do so
"clearly".
While the efficiency might be
minor a minor difference is enough for me. In cases like this were it's
pretty much the same either way a small difference tips the scales.

Nope. There are significant differences in the higher-level aspects of
using an override versus an event. The design issues clearly win out
over any insignificant efficiency issue.

Pete
 
Smithers said:
The intent behind my OP [of this thread] is to learn best practices and
such. So I'm very much interested in learning about accepted norms that
may be floating around - of which I may be unaware. If you have "checked
out" of caring about this thread and don't want to post specific links,
can you at least reply with some key words or phrases that I can google to
discover this norm of which you write?

I don't have any specific links, I have just read *many* times over the
years that events are not super efficient. Despite peter's protests I don't
think it's a radical statement to say this is fairly well accepted. In the
case of the event you have the delegate which is a seperate object. This
needs to hold a reference to the object which receives the event and needs
to check that that object exists before calling it. It needs to enumerate
the list of receiving objects when raising the event and the garbage
collector needs to destroy all of this in the correct order. On the other
hand with the override you need to inherit from Form anyway so overriding 1
function is going to make little difference. This does not mean you should
avoid using events as it generally matters little but if a method is more
efficient and pretty much equal then you may as well use it.

Search terms would be Delegate, Multicast, Events, Overrides and C#.

Michael
 
Peter Duniho said:
You fail to comprehend that this is not just about "my misunderstanding".
It is also about "your misunderstanding". So far, the only thing
objective posted to this thread has been by me, showing your own
misunderstanding.
Funny.

This isn't about "the educating I need". This is about getting the facts
right. If you can't be bothered, what you can't be bothered with is
getting the facts right.

Your own arrogance, insisting that you are right without be able to be
bothered to investigate whether that's true or not, is getting in your own
way of learning something.

Events are well known to be less efficient, I have read this *many* times
over the years and have accepted it long ago. If you want to disprove it
then go ahead.

Me silly.
I must have missed where that happened.

Not the first time, you'll be telling me again how you've missed nothing.
Please show me where my tests "were clearly shown to be flawed". All
you've posted is conjecture. You certainly have suggested my test was
flawed, but you've done absolutely nothing to _show_ they are flawed,
never mind do so "clearly".

I have shown they are missing the attachment of the event. All you are
testing is the speed of calling an event without even checking if exists. If
you don't think that's flawed then what can I say. I suspect you've tried
these things and found the event to be less efficient so haven't posted the
results.
Nope. There are significant differences in the higher-level aspects of
using an override versus an event. The design issues clearly win out over
any insignificant efficiency issue.

Maybe in some cases, but 99% of the time it makes no difference except the
efficiency.

Michael
 
Back
Top