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

"is" vs. "as"

P: n/a
Is there an advantage to either of these methods, or is it simply a matter
of style? I used to use the "as" method, but later gave it up for the "is"
method as the intent of the code seems a little clearer to me. I now have
some projects coming up where the baseTypeCollection will contain 5k to 10k
objects that will have to be searched for various sub types of which I only
expect to find ~50 to ~100 matches. Thanks!

foreach (baseType in baseTypeCollection)
{
if (baseType is desiredSubType)
{
typeFound = (desiredSubType) baseType;
//do my thing with typeFound
}
}
foreach (baseType in baseTypeCollection)
{
typeFound = baseType as desiredSubType;
if (typeFound != null)
{
//do my thing with typeFound
}
}

--
Bobby C. Jones
www.AcadX.com
Nov 15 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a
Well the first one is more natural to read.
"Bobby C. Jones" <bobbyj (at) acadx (dot) com> wrote in message
news:#g**************@TK2MSFTNGP10.phx.gbl...
Is there an advantage to either of these methods, or is it simply a matter
of style? I used to use the "as" method, but later gave it up for the "is" method as the intent of the code seems a little clearer to me. I now have
some projects coming up where the baseTypeCollection will contain 5k to 10k objects that will have to be searched for various sub types of which I only expect to find ~50 to ~100 matches. Thanks!

foreach (baseType in baseTypeCollection)
{
if (baseType is desiredSubType)
{
typeFound = (desiredSubType) baseType;
//do my thing with typeFound
}
}
foreach (baseType in baseTypeCollection)
{
typeFound = baseType as desiredSubType;
if (typeFound != null)
{
//do my thing with typeFound
}
}

--
Bobby C. Jones
www.AcadX.com

Nov 15 '05 #2

P: n/a
Hi Bobby,

"Bobby C. Jones" <bobbyj (at) acadx (dot) com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Is there an advantage to either of these methods, or is it simply a matter
of style? I used to use the "as" method, but later gave it up for the "is" method as the intent of the code seems a little clearer to me. I now have
some projects coming up where the baseTypeCollection will contain 5k to 10k objects that will have to be searched for various sub types of which I only expect to find ~50 to ~100 matches. Thanks!

foreach (baseType in baseTypeCollection)
{
if (baseType is desiredSubType)
{
typeFound = (desiredSubType) baseType;
//do my thing with typeFound
}
}
foreach (baseType in baseTypeCollection)
{
typeFound = baseType as desiredSubType;
if (typeFound != null)
{
//do my thing with typeFound
}
}


Using "as" is more performat than using "is" because there is only one
cast instead of two. In most scenarios I would say the difference is
negligable, but given your scenario, you may just notice a difference.

Regards,
Dan
Nov 15 '05 #3

P: n/a
Bobby,

In a previous post, Greg Ewing found that when doing comparisons with
is, it is about 10X faster then checking using "as" or doing an equality
operation with GetType/typeof.

However, for what you are doing, I think that you can go one step
further. I think that what you should do is in your collection, have a
hashtable. This hashtable should be keyed on the type of the items that are
kept in the collection. The values in the hashtable are collections of the
items of that type.

So, when you add an element, you would check the type. Then look in the
hashtable against that type. Get the collection of items of that type, and
add a reference to the new value in your collection there. Also, make sure
to do the same when deleting.

Then, when you want to query for the elements that are of a particular
type, you don't have to enumerate through such a large number of items.
Granted, the insert and deletes are going to be a little slower, but
overall, if you do this kind of select often, it should increase the overall
efficiency of the class.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Bobby C. Jones" <bobbyj (at) acadx (dot) com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Is there an advantage to either of these methods, or is it simply a matter
of style? I used to use the "as" method, but later gave it up for the "is" method as the intent of the code seems a little clearer to me. I now have
some projects coming up where the baseTypeCollection will contain 5k to 10k objects that will have to be searched for various sub types of which I only expect to find ~50 to ~100 matches. Thanks!

foreach (baseType in baseTypeCollection)
{
if (baseType is desiredSubType)
{
typeFound = (desiredSubType) baseType;
//do my thing with typeFound
}
}
foreach (baseType in baseTypeCollection)
{
typeFound = baseType as desiredSubType;
if (typeFound != null)
{
//do my thing with typeFound
}
}

--
Bobby C. Jones
www.AcadX.com

Nov 15 '05 #4

P: n/a
Thanks Nicholas and everyone! This is some great info to know.

The collection is actually one that I am receiving from a COM server, not
one that I'm creating myself. I had actually considered something like what
you are suggesting here Nicholas as the COM server does provide event
notification when objects are added and removed. But I wanted to wait and
see if iterating the entire collection will become a bottleneck or not
before adding the code to optimize the searches. This could be feasible and
not to damaging to my app's memory footprint because I won't need to search
for all of the subtypes, only a handful. I could just cache those types, or
even dynamically cache them as needed...Hmm...thanks for helping to get the
brain juices flowing!
--
Bobby C. Jones
www.AcadX.com
Nov 15 '05 #5

P: n/a
You cant have duplicates in a Hashtable so how do you propose keying on
Type? Only one type alowed at any one time?
"Bobby C. Jones" <bobbyj (at) acadx (dot) com> wrote in message
news:#A**************@TK2MSFTNGP09.phx.gbl...
Thanks Nicholas and everyone! This is some great info to know.

The collection is actually one that I am receiving from a COM server, not
one that I'm creating myself. I had actually considered something like what you are suggesting here Nicholas as the COM server does provide event
notification when objects are added and removed. But I wanted to wait and
see if iterating the entire collection will become a bottleneck or not
before adding the code to optimize the searches. This could be feasible and not to damaging to my app's memory footprint because I won't need to search for all of the subtypes, only a handful. I could just cache those types, or even dynamically cache them as needed...Hmm...thanks for helping to get the brain juices flowing!
--
Bobby C. Jones
www.AcadX.com

Nov 15 '05 #6

P: n/a
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
In a previous post, Greg Ewing found that when doing comparisons with
is, it is about 10X faster then checking using "as" or doing an equality
operation with GetType/typeof.


No - he found it was ten times faster than doing an equality check with
GetType/typeof. as/is were roughly the same speed, I believe - that
would certainly make sense, although if you then need to cast, "as"
should be faster.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #7

P: n/a
The original poster (OP) indicated that the collection was storing
references of a base type. He is searching for the derived types in the
collection. The hashtable is going to be keyed on the type of the value
that is stored in the collection (GetType returns the type of the instance,
not the type of the reference).

The hashtable would store another collection, which has the references
to the values that are in the main collection, and provides an easy way to
look them up based on the type.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"news.microsoft.com" <di********@discussion.microsoft.com> wrote in message
news:uA**************@tk2msftngp13.phx.gbl...
You cant have duplicates in a Hashtable so how do you propose keying on
Type? Only one type alowed at any one time?
"Bobby C. Jones" <bobbyj (at) acadx (dot) com> wrote in message
news:#A**************@TK2MSFTNGP09.phx.gbl...
Thanks Nicholas and everyone! This is some great info to know.

The collection is actually one that I am receiving from a COM server, not one that I'm creating myself. I had actually considered something like what
you are suggesting here Nicholas as the COM server does provide event
notification when objects are added and removed. But I wanted to wait and see if iterating the entire collection will become a bottleneck or not
before adding the code to optimize the searches. This could be feasible

and
not to damaging to my app's memory footprint because I won't need to

search
for all of the subtypes, only a handful. I could just cache those

types, or
even dynamically cache them as needed...Hmm...thanks for helping to get

the
brain juices flowing!
--
Bobby C. Jones
www.AcadX.com


Nov 15 '05 #8

P: n/a
Jon,

Nope, these are the numbers that he posted:

Using the is operator took 00:00:00.0000240
Using GetType() took 00:00:00.0002363
Using the as operator took 00:00:00.0002394

The as operator was the slowest of them all.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
In a previous post, Greg Ewing found that when doing comparisons with is, it is about 10X faster then checking using "as" or doing an equality
operation with GetType/typeof.


No - he found it was ten times faster than doing an equality check with
GetType/typeof. as/is were roughly the same speed, I believe - that
would certainly make sense, although if you then need to cast, "as"
should be faster.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #9

P: n/a
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
Nope, these are the numbers that he posted:

Using the is operator took 00:00:00.0000240
Using GetType() took 00:00:00.0002363
Using the as operator took 00:00:00.0002394

The as operator was the slowest of them all.


Oops. In that case, I'm afraid I question the testing methodology *or*
Whidbey has *completely* different behaviour to v1.1, which it may do
for the beta, of course.

(Note that the code originally posted didn't even test it 1000 times,
so I'm assuming that wasn't the code that was actually run.)

Here's code that can run under .NET 1.1, and then the results:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

class Stopwatch
{
DateTime start;
DateTime stop;

internal TimeSpan Elapsed
{
get
{
return stop-start;
}
}

internal void Start()
{
start = DateTime.Now;
}

internal void Stop()
{
stop = DateTime.Now;
}
}

class Class1
{

const int Iterations = 100000000;

static void Main(string[] args)
{
Control ctl = new DropDownList();
Stopwatch sw = new Stopwatch();
int j = 0;
sw.Start();
for (int i = 0; i < Iterations; i++)
{
if (ctl is System.Web.UI.WebControls.DropDownList)
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}
sw.Stop();
Console.WriteLine("Using the is operator took " + sw.Elapsed);

sw.Start();
for (int i = 0; i < Iterations; i++)
{
if (ctl.GetType() == typeof
System.Web.UI.WebControls.DropDownList))
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}

sw.Stop();
Console.WriteLine("Using GetType() took " + sw.Elapsed);

sw.Start();
for (int i=0; i < Iterations; i++)
{
if ((ctl as System.Web.UI.WebControls.DropDownList)
!= null)
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}
sw.Stop();
Console.WriteLine("Using the as operator took " + sw.Elapsed);
Console.Read();
}
}

My results:
Using the is operator took 00:00:00.7031250
Using GetType() took 00:00:04.9531250
Using the as operator took 00:00:00.5000000

Looking at the IL for the as/is cases, they look identical to me (I
suspect the variance in time shown above is due to JITting through the
as case, but I haven't investigated further). As I understand it,

if (x is Y)

is always transformed into exactly the same code as

if ((x as Y) != null)
When you then cast, it's cheaper to just use "as" a single time, as
that only requires the check to be performed once.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #10

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
Looking at the IL for the as/is cases, they look identical to me (I
suspect the variance in time shown above is due to JITting through the
as case, but I haven't investigated further). As I understand it,
I also get similar performance for 'as' and 'is' on framework 1.0.
if (x is Y)
is always transformed into exactly the same code as
if ((x as Y) != null)


On the contrary, if you look at the IL you see that 'as' is converted to an
'is'. This makes sense because 'as' cannot be used for value types, while
'is' can.

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl
Nov 15 '05 #11

P: n/a
Dont use DateTime

Wrap QueryPerformanceCounter and QueryPerformanceFrequency native API

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
Nope, these are the numbers that he posted:

Using the is operator took 00:00:00.0000240
Using GetType() took 00:00:00.0002363
Using the as operator took 00:00:00.0002394

The as operator was the slowest of them all.


Oops. In that case, I'm afraid I question the testing methodology *or*
Whidbey has *completely* different behaviour to v1.1, which it may do
for the beta, of course.

(Note that the code originally posted didn't even test it 1000 times,
so I'm assuming that wasn't the code that was actually run.)

Here's code that can run under .NET 1.1, and then the results:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

class Stopwatch
{
DateTime start;
DateTime stop;

internal TimeSpan Elapsed
{
get
{
return stop-start;
}
}

internal void Start()
{
start = DateTime.Now;
}

internal void Stop()
{
stop = DateTime.Now;
}
}

class Class1
{

const int Iterations = 100000000;

static void Main(string[] args)
{
Control ctl = new DropDownList();
Stopwatch sw = new Stopwatch();
int j = 0;
sw.Start();
for (int i = 0; i < Iterations; i++)
{
if (ctl is System.Web.UI.WebControls.DropDownList)
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}
sw.Stop();
Console.WriteLine("Using the is operator took " + sw.Elapsed);

sw.Start();
for (int i = 0; i < Iterations; i++)
{
if (ctl.GetType() == typeof
System.Web.UI.WebControls.DropDownList))
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}

sw.Stop();
Console.WriteLine("Using GetType() took " + sw.Elapsed);

sw.Start();
for (int i=0; i < Iterations; i++)
{
if ((ctl as System.Web.UI.WebControls.DropDownList)
!= null)
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}
sw.Stop();
Console.WriteLine("Using the as operator took " + sw.Elapsed);
Console.Read();
}
}

My results:
Using the is operator took 00:00:00.7031250
Using GetType() took 00:00:04.9531250
Using the as operator took 00:00:00.5000000

Looking at the IL for the as/is cases, they look identical to me (I
suspect the variance in time shown above is due to JITting through the
as case, but I haven't investigated further). As I understand it,

if (x is Y)

is always transformed into exactly the same code as

if ((x as Y) != null)
When you then cast, it's cheaper to just use "as" a single time, as
that only requires the check to be performed once.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #12

P: n/a
"news.microsoft.com" <di********@discussion.microsoft.com> wrote
Dont use DateTime


If you're using enough iterations, DateTime is fine. On my computer the
different loops take between 1.3s and 11s. If you know that DateTime has a
resolution of around 10ms, I'm sure that you'll agree it's good enough.

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl
Nov 15 '05 #13

P: n/a
Jon,

FYI these are the whidbey results on a 1Ghz PIII

Using the is operator took 00:00:01.1315933
Using GetType() took 00:00:02.6637506
Using the as operator took 00:00:01.0214382

Good to see GetType got a los faster (as a lot of others :-))
Willy.

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message news:MP************************@msnews.microsoft.c om...
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard.caspershouse.com> wrote:
Nope, these are the numbers that he posted:

Using the is operator took 00:00:00.0000240
Using GetType() took 00:00:00.0002363
Using the as operator took 00:00:00.0002394

The as operator was the slowest of them all.


Oops. In that case, I'm afraid I question the testing methodology *or*
Whidbey has *completely* different behaviour to v1.1, which it may do
for the beta, of course.

(Note that the code originally posted didn't even test it 1000 times,
so I'm assuming that wasn't the code that was actually run.)

Here's code that can run under .NET 1.1, and then the results:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

class Stopwatch
{
DateTime start;
DateTime stop;

internal TimeSpan Elapsed
{
get
{
return stop-start;
}
}

internal void Start()
{
start = DateTime.Now;
}

internal void Stop()
{
stop = DateTime.Now;
}
}

class Class1
{

const int Iterations = 100000000;

static void Main(string[] args)
{
Control ctl = new DropDownList();
Stopwatch sw = new Stopwatch();
int j = 0;
sw.Start();
for (int i = 0; i < Iterations; i++)
{
if (ctl is System.Web.UI.WebControls.DropDownList)
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}
sw.Stop();
Console.WriteLine("Using the is operator took " + sw.Elapsed);

sw.Start();
for (int i = 0; i < Iterations; i++)
{
if (ctl.GetType() == typeof
System.Web.UI.WebControls.DropDownList))
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}

sw.Stop();
Console.WriteLine("Using GetType() took " + sw.Elapsed);

sw.Start();
for (int i=0; i < Iterations; i++)
{
if ((ctl as System.Web.UI.WebControls.DropDownList)
!= null)
{
j++;
//Console.WriteLine("ctl is a DropDownList");
}
else
{
j++;
//Console.WriteLine("ctl is NOT a DropDownList");
}
}
sw.Stop();
Console.WriteLine("Using the as operator took " + sw.Elapsed);
Console.Read();
}
}

My results:
Using the is operator took 00:00:00.7031250
Using GetType() took 00:00:04.9531250
Using the as operator took 00:00:00.5000000

Looking at the IL for the as/is cases, they look identical to me (I
suspect the variance in time shown above is due to JITting through the
as case, but I haven't investigated further). As I understand it,

if (x is Y)

is always transformed into exactly the same code as

if ((x as Y) != null)
When you then cast, it's cheaper to just use "as" a single time, as
that only requires the check to be performed once.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #14

P: n/a
> In a previous post, Greg Ewing found that when doing comparisons with
is, it is about 10X faster then checking using "as" or doing an equality
operation with GetType/typeof.
That doesn't seem to be correct???

--
-----------
Got TidBits?
Get it here: www.networkip.net/tidbits
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:e#**************@TK2MSFTNGP12.phx.gbl... Bobby,

In a previous post, Greg Ewing found that when doing comparisons with
is, it is about 10X faster then checking using "as" or doing an equality
operation with GetType/typeof.

However, for what you are doing, I think that you can go one step
further. I think that what you should do is in your collection, have a
hashtable. This hashtable should be keyed on the type of the items that are kept in the collection. The values in the hashtable are collections of the items of that type.

So, when you add an element, you would check the type. Then look in the hashtable against that type. Get the collection of items of that type, and add a reference to the new value in your collection there. Also, make sure to do the same when deleting.

Then, when you want to query for the elements that are of a particular
type, you don't have to enumerate through such a large number of items.
Granted, the insert and deletes are going to be a little slower, but
overall, if you do this kind of select often, it should increase the overall efficiency of the class.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Bobby C. Jones" <bobbyj (at) acadx (dot) com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Is there an advantage to either of these methods, or is it simply a matter of style? I used to use the "as" method, but later gave it up for the

"is"
method as the intent of the code seems a little clearer to me. I now have some projects coming up where the baseTypeCollection will contain 5k to

10k
objects that will have to be searched for various sub types of which I

only
expect to find ~50 to ~100 matches. Thanks!

foreach (baseType in baseTypeCollection)
{
if (baseType is desiredSubType)
{
typeFound = (desiredSubType) baseType;
//do my thing with typeFound
}
}
foreach (baseType in baseTypeCollection)
{
typeFound = baseType as desiredSubType;
if (typeFound != null)
{
//do my thing with typeFound
}
}

--
Bobby C. Jones
www.AcadX.com


Nov 15 '05 #15

P: n/a
Alvin Bruney <vapordan_spam_me_not@hotmail_no_spamhotmail.com > wrote:
In a previous post, Greg Ewing found that when doing comparisons with
is, it is about 10X faster then checking using "as" or doing an equality
operation with GetType/typeof.


That doesn't seem to be correct???


It's correct that Greg posted it (I blundered there) - but the results
aren't consistent with behaviour on the shipping framework, at least,
or Willy's installation of Whidbey.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.