By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,853 Members | 1,570 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,853 IT Pros & Developers. It's quick & easy.

Performance of operators is/as vs cast

P: n/a
There was an earlier discussion regarding which one is faster - a
throwing cast - "(Foo)obj", or a non-throwing one - "obj as Foo", when
both are available for a given type and value. The consensus was that,
since a check has to be made by the compiler in either case, the speed
should be equivalent in case object is indeed of a requested type.
Sounds perfectly reasonable, but I've spotted the following in
the .NET source code (from MS symbol servers) today, in file
BindingList.cs, method Child_PropertyChanged:

// The change event is broken should someone pass
an item to us that is not
// of type T. Still, if they do so, detect it and
ignore. It is an incorrect
// and rare enough occurrence that we do not want
to slow the mainline path
// with "is" checks.
T item;
try {
item = (T)sender;
}
catch(InvalidCastException) {
ResetBindings();
return;
}

Now this gets interesting, since the comment clearly implies that a
throwing cast is, after all, faster than a check for the non-throw
case (and since "is" and "as" are both compiled to "isinst" IL, we
know that it is really about "castclass" vs "isinst"). I wonder how
true this really is, and if so, why is it the case. I'm going to play
with debugger to see what the JIT produces in either case later, but
perhaps someone already knows the reason?
Jun 27 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
implies that a throwing cast is, after all, faster than a check for the non-throw
No - the point here is that even if they do an "is" test, they are
*still* going to have to do the cast. BindingList<Tdoesn't impose
that T : class, so "as" isn't an option, so they would have to write:

if(sender is T) {
T item = (T) sender;
}

So they've only introduced *extra* code by using "is"; the cast will
still do the check anyway. And as the comment explains, the exception
is expected to be the rare case, so it makes reasonable sense to
simply catch it if a problem happens. In reality: we are talking about
data-binding here - lots of events/delegate invokes/indirection via
System.ComponentModel. Minute things like the difference between is/as/
cast are going to be such a tiny portion of the overall CPU cost that
even if it was done the most expensive way (of the three mentioned) it
would never manifest as a bottleneck; and I'd rather MS concentrate on
the bigger picture ;-p

Marc
Jun 27 '08 #2

P: n/a
On Tue, 24 Jun 2008 23:52:48 -0700, Marc Gravell <ma**********@gmail.com
wrote:
>implies that a throwing cast is, after all, faster than a check for the
non-throw

No - the point here is that even if they do an "is" test, they are
*still* going to have to do the cast. BindingList<Tdoesn't impose
that T : class, so "as" isn't an option, so they would have to write:

if(sender is T) {
T item = (T) sender;
}
To be fair, I think they'd have written:

T item = sender as T;

if (item != null)
{
...
}

Now, whether that's in fact more costly than casting in the successful
case, I don't know. But let's make sure we're comparing apples to apples
here, rather than introducing some artificial performance problem. :)

Do you have some reason to believe that they wouldn't write the above,
rather than the code you suggested? Or are you saying that writing "as"
winds up basically doing the "is" followed by the cast, just hidden by the
compiler?
[...] Minute things like the difference between is/as/
cast are going to be such a tiny portion of the overall CPU cost that
even if it was done the most expensive way (of the three mentioned) it
would never manifest as a bottleneck;
I agree, which begs the question: why did the author of that code think it
was important enough not only to write it that way, but to specifically
call out a performance difference?

It's a bit of a moot question, I realize. After all, even if a
performance optimization is deemed worthwhile within the framework, that
doesn't mean the same optimization is justifiable in end-user code. ButI
admit to having my curiosity piqued, now that the question has been
asked. It'd be nice to have something a little more definitive as an
answer, I think.

Pete
Jun 27 '08 #3

P: n/a
To be fair, I think they'd have written:

No; they *can't* have; I'll repeat: BindingList<Tdoes not impose
that T : class, therefore the following is invalid:

T item = sender as T;
Error 1 The type parameter 'T' cannot be used with the 'as' operator
because it does not have a class type constraint nor a 'class'
constraint

Add that in with the rest of the comments, and I think that explains
everything.

Marc
Jun 27 '08 #4

P: n/a
On Wed, 25 Jun 2008 00:32:56 -0700, Marc Gravell <ma**********@gmail.com>
wrote:
>To be fair, I think they'd have written:

No; they *can't* have; I'll repeat: BindingList<Tdoes not impose
that T : class
Ah, okay. I guess the answer to my question "Do you have some reason to
believe that they wouldn't write the above" is "yes" then. :)

Teach me to post when I'm sleep deprived. I apparently skipped over some
important words in your previous post. Thanks for the clarification.

All that said, I still agree that I find it odd that they'd go out of
their way to avoid using "is", given that there are probably better ways
to spend their time. :)

Pete
Jun 27 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.