casting vs creating an instance

  • Thread starter Yankee Imperialist Dog
  • Start date
Y

Yankee Imperialist Dog

I'm doing my c# more and more like i used to code c++, meaning i'm casting
more often than creating an instance of objects.
like :
protected void gvOrderDetailsRowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
switch (((Sale)e.Row.DataItem).SzPN)
{
case "LTM0001":
case "ANU0001":
Person PER =
PersonManager.GetItem(((Sale)e.Row.DataItem).IPersonID);
if (PER.BActive)
((Label)e.Row.FindControl("lblOwner")).Text =
PER.FullName;
else
((Label)e.Row.FindControl("lblOwner")).Text = "Not
Yet Active";
break;
default:
break;
}
}
}

would an instance created once for (Sale)e.Row.DataItem,
where the row is bound to a custom business object, be faster, slow or no
different than just casting the e.row.DataItem each time i need a value?
 
B

Bob Powell [MVP]

Y

Yankee Imperialist Dog

that is possible. Does creating an instance take time at runtime where a cast
would not?
 
J

Jon Skeet [C# MVP]

You seem to be inferring that a cast takes time at runtime.

You seem to be implying that it doesn't ;)

Unless the compiler can guarantee that the cast is valid (and not even
then, sometimes) the cast *will* take time at execution time. Not a
lot, but some.

To the OP: I wouldn't worry about the performance side, but the
clarity side. Creating a new object and reuing an old one are usually
significantly different operations, wiith different implications. Go
with whatever produces the cleanest, most natural code. If you're
logically operating on an existing object, do so - if you're logically
creating a new one, do that instead :)

Jon
 
Y

Yankee Imperialist Dog

Thank You for replying, all of you.
Perhaps my terms were off and i stand corrected. The local variable in my
case is a class and as it is atomic in it's scope i guess this does make it a
variable. The root here is memory usage and time. From what all of you said
it seems that there really is no difference. Creating a variable of type
"Sale" and storing all the objects from the data row is not any different
than time or memory wise than casting for each object i need from that data
row.

Please correct me if i am wrong here

Thanks
--
Share The Knowledge. I need all the help I can get and so do you!


Peter Duniho said:
[...]
would an instance created once for (Sale)e.Row.DataItem,
where the row is bound to a custom business object, be faster, slow or no
different than just casting the e.row.DataItem each time i need a value?

As Bob's reply suggests, casting really isn't a performance issue. It's
not true that it's completely free -- unless the compiler can tell that
the cast is perfectly safe (and most of the time, it can't), there's a
run-time check for the type. But the check is relatively insignificant.

That said, the real issue here is that you seem to be under the impression
that casting is equivalent to _creating_ an instance of an object. It's
not.

Now, it's possible that when you write "an instance created once", you
really just mean casting the value once as you assign it to a local
variable. And in fact, I would do that. Not because it's more
performant, but just because if you're using the value more than once, it
makes the code nicer to read.

But doing the cast doesn't create an instance, not even if you do it when
assigning to a local variable of the target type. If you're trying to
learn C#, it will be important for you to be careful about correctly
describing what the code is doing, and in particular describing a simple
assignment as "creating an instance" is incorrect and will likely lead to
misunderstandings in the future if that description continues to be used.

Pete
 
J

Jon Skeet [C# MVP]

Thank You for replying, all of you.
Perhaps my terms were off and i stand corrected. The local variable in my
case is a class and as it is atomic in it's scope i guess this does make it a
variable. The root here is memory usage and time. From what all of you said
it seems that there really is no difference. Creating a variable of type
"Sale" and storing all the objects from the data row is not any different
than time or memory wise than casting for each object i need from that data
row.

Please correct me if i am wrong here

It feels like your terminology is still a bit off - a class can't be
atomic, for example.

Could you post a short but *complete* program demonstrating what you
mean?

Certainly creating instances and casting *are* different in time and
memory, but whether or not they're *significantly* different will
depend on the situation.

Jon
 
Y

Yankee Imperialist Dog

i'll describe

Sale is a class. Having firstname, lastname, .......
if i create an object ("by casting the DataItem to type of Sale)
Sale SAL = ((Sale)e.row.DataItem;
if (SAL.SzPn == "YYY")
SAL.FirstName;
SAL.LastName;


if i cast the DataItem to
if (((Sale)e.Row.DataItem).SzPN == "YYY")
(((Sale)e.Row.DataItem).SzFirstName;
(((Sale)e.Row.DataItem).SzLastName;
....;
ok I think we can agree that SAL it is an object of Type Sale. The question
here is, as implied from other answers/comments above. Is SAL a "Variable" of
Type Sale or an "Instance" of type Sale. I, up to this point, would have
considered it an instance. However, it suggested above by another poster
(Peter) that it should be considered a variable(?) Now i understand that it's
values can vary, but i've always considered an object created from a class to
be an instance(?)

That asside say i'm going to be setting the 50 public properties of object SAL
is there a time or memory difference between
Sale SAL = ((Sale)e.row.DataItem;
SAL.FirstName = "TTT";
....
....
... to property #50
and
(((Sale)e.Row.DataItem).SzFirstName = "TTT";
....
....
.... to row 50

It may be splitting hairs, but I'm curious, because i tend to like the latter.

Thanks
 
J

Jon Skeet [C# MVP]

i'll describe

Sale is a class. Having firstname, lastname, .......
if i create an object ("by casting the DataItem to type of Sale)
Sale SAL = ((Sale)e.row.DataItem;

What makes you think that's creating an object? It's not. It's not
creating anything, it's just casting a reference.
if (SAL.SzPn == "YYY")
SAL.FirstName;
SAL.LastName;

if i cast the DataItem to
if (((Sale)e.Row.DataItem).SzPN == "YYY")
(((Sale)e.Row.DataItem).SzFirstName;
(((Sale)e.Row.DataItem).SzLastName;
....;
ok I think we can agree that SAL it is an object of Type Sale. The question
here is, as implied from other answers/comments above. Is SAL a "Variable" of
Type Sale or an "Instance" of type Sale.

SAL itself is definitely a variable.
I, up to this point, would have
considered it an instance. However, it suggested above by another poster
(Peter) that it should be considered a variable(?) Now i understand that it's
values can vary, but i've always considered an object created from a class to
be an instance(?)

It's neither an object, nor an instance. It's a variable. It's a local
variable which has a particular value.

Here's another example:

int x = 0;

"x" isn't an int. It's a variable of type int. The *value* of x is an
int.
That asside say i'm going to be setting the 50 public properties of object SAL
is there a time or memory difference between
Sale SAL = ((Sale)e.row.DataItem;
SAL.FirstName = "TTT";
....
....
... to property #50
and
(((Sale)e.Row.DataItem).SzFirstName = "TTT";
...
...
... to row 50

It may be splitting hairs, but I'm curious, because i tend to like the latter.

Well it doesn't make sense to perform a cast 60 times or indeed
evaluate the Row and DataItem properties 60 times, and personally I
don't like the readability of the version which casts all the time, so
I'd use the former. What do you like about the latter?

Jon
 
B

Ben Voigt [C++ MVP]

That asside say i'm going to be setting the 50 public properties of
object SAL is there a time or memory difference between
Sale SAL = ((Sale)e.row.DataItem;
SAL.FirstName = "TTT";
....
....
... to property #50
and
(((Sale)e.Row.DataItem).SzFirstName = "TTT";
...
...
... to row 50

It may be splitting hairs, but I'm curious, because i tend to like
the latter.

The first is undoubtedly at least as good as the second and probably much
much better. You save not just a cast, but two property accessors and a
cast, on each line. Depending on whether you are using interfaces, how
complex the property accessors are, they may be inlined anyway, but the
compiler probably cannot infer that the same value is returned each time.
Since you know that, it's best to help the compiler out by storing it in a
local variable.

And while cast syntax can create a new instance if it invokes a user-defined
conversion operator, upcasts and downcasts don't. There are no new
instances going on here, just saving the result of the cache in order to
avoid recalculating it.
 
Y

Yankee Imperialist Dog

lol Point taken my friend. In truth i'd more than likely use Reflection where
i could and live with the performance hit where 60 needed. I guess i was
just trying to get an answer as to if there was a difference in terms of
performance. Consider it an accademic issue.

As was pointed out by Peter, I tend to get sloppy on terms, but i really do
try to make the code fun as well as readable.
 
Y

Yankee Imperialist Dog

Thank you for responding. Deep down i understood all that and i did use the
wrong words. You point was taken.

--
Share The Knowledge. I need all the help I can get and so do you!


Peter Duniho said:
i'll describe

Sale is a class. Having firstname, lastname, .......
if i create an object ("by casting the DataItem to type of Sale)
Sale SAL = ((Sale)e.row.DataItem;

That's not an example of "create an object".

Perhaps I wasn't emphatic enough before: it is ABSOLUTELY CRITICAL that
you use the correct terminology. Even in daily communication, using words
in their normal, expected way is important. But in a technical field like
programming, we have very specific concepts and very specific words and
phrases to describe those concepts. As a community we've already agreed
upon the usage, and if you start using words and phrases to mean something
than what they already mean, it's very difficult to understand what you
mean.

At best, we have to guess from the context what you're really talking
about and at worst, we can collectively waste a whole lot of time
answering a completely different question from what you've asked.
[...]
ok I think we can agree that SAL it is an object of Type Sale. The
question
here is, as implied from other answers/comments above. Is SAL a
"Variable" of
Type Sale or an "Instance" of type Sale.

Sorry to be the bearer of bad news, but that's only a question in your
mind. :)
I, up to this point, would have
considered it an instance. However, it suggested above by another poster
(Peter) that it should be considered a variable(?) Now i understand that
it's
values can vary, but i've always considered an object created from a
class to
be an instance(?)

You didn't _create_ the object with the cast. You cast an existing
reference to an existing object from one type to another. The only thing
that changed was how your code views the object. The actual object didn't
change, and no new object was created.

And yes, "SAL" is a variable. It is not the object itself, but rather a
reference to the object. When you cast a different reference to the type
"Sale", you assigned the exact same value that was in "e.Row.DataItem" to
the variable "SAL". The cast doesn't change the value, it just tells the
compiler "yes, I really meant to do this". Then at run-time, the .NET
Framework run-time checks the types for each variable (the source
"e.Row.DataItem" and the destination "SAL") and verifies that what's
contained in the source is in fact compatible with the destination (i.e.
makes sure that it's actually a instance of "Sale").

This run-time check takes a little time, and that's why we've said there's
some overhead. But the time spent is _really_ small. It's not of any
concern in most code, and even in code where performance is critical,
avoiding multiple casts is highly unlikely to be an optimization that
would be of any use.
That asside say i'm going to be setting the 50 public properties of
object SAL
is there a time or memory difference between
Sale SAL = ((Sale)e.row.DataItem;
SAL.FirstName = "TTT";
....
....
... to property #50
and
(((Sale)e.Row.DataItem).SzFirstName = "TTT";

Well, you could in fact test it yourself. But no, I do not believe you
would be able to find any measurable, significant difference between the
two, even though there's a theoretical performance difference.
...
...
... to row 50

It may be splitting hairs, but I'm curious, because i tend to like the
latter.

Well, if you like the latter, use it. Personally, I find the latter
harder to read and more verbose. As I mentioned before, I'd prefer the
former. But if you really really like the latter, there's no real
performance reason to avoid it.

Pete
 
Y

Yankee Imperialist Dog

I appreciate the references. Yes the code is as you say. Some times it's fun
to do something just to be different life's to short. Just being curious
about performance. Pretty don't always mean smart. However, as i noted below
i'd use reflection if i had to set 50 or more if i could.

Programmer time is often more costly than computer time needed to execute,
but not always. Just got to know when to do what.
 
Y

Yankee Imperialist Dog

To every one: This has been a fun discussion i really think this is how
knowledge gets shared. I take no offence to any comments and i do not intend
to offend.

Thanks. I tearned something from each of you!!
 
B

Bob Powell [MVP]

I think that the times type checking is employed at runtime are pretty
infrequent, especially for common cases.

I tried the following;

#1 a class cast to an interface
#2 direct call to the classes implementation
#3 direct call to a class method not used as an interface implementation
#4 call to a derived class cast to a base
#5 direct call to a derived class method
#6 cast from variable of type object to specific type

in all cases the compiler worked out the correct info and the IL was pretty
much the same except for the type of the final object.

To clarify;

#1 object was type a
#2 object was type a
#3 object was type a
#4 object was type aderived
#5 object was of type aderived
#6 object was of type a

The stopwatch times to make 10000 calls to methods that themselves made a
thousand iterations, non optimised, were virtually identical.

While I understand that the circumstance arises occasionally, as a
performance issue, I think the question of casting is a non-starter.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
J

Jon Skeet [C# MVP]

Bob Powell said:
I think that the times type checking is employed at runtime are pretty
infrequent, especially for common cases.

Absolutely not. Almost every time I use a cast, it's for something
which requires an execution time test. The common case is precisely
like the OP's, in my view, and that certainly requires execution time
testing.
I tried the following;

#1 a class cast to an interface

If the class is known to implement the interface at compile-time,
that's redundant. If not, it requires an execution time test.
#2 direct call to the classes implementation
#3 direct call to a class method not used as an interface implementation
#4 call to a derived class cast to a base

No execution time test required here - and no cast required unless
you're trying to affect overloading.
#5 direct call to a derived class method
#6 cast from variable of type object to specific type

And this last one is the important one.
in all cases the compiler worked out the correct info and the IL was pretty
much the same except for the type of the final object.

To clarify;

#1 object was type a
#2 object was type a
#3 object was type a
#4 object was type aderived
#5 object was of type aderived
#6 object was of type a

The stopwatch times to make 10000 calls to methods that themselves made a
thousand iterations, non optimised, were virtually identical.

While I understand that the circumstance arises occasionally, as a
performance issue, I think the question of casting is a non-starter.

If you're trying to test the cost of casting, why are you also
introducing a method call? I'd also question the value of testing
*redundant* casts - sure, they don't take time at execution time, but
they're also not needed even at compile time.

Here's a test program to *just* test casting as far as possible:

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

class Test
{
static void Main(string[] args)
{
int iterations = int.Parse(args[0]);
Stopwatch sw = Stopwatch.StartNew();

for (int i=0; i < iterations; i++)
{
object x = GetSampleObject();
//string x = (string) GetSampleObject();
}

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static object GetSampleObject()
{
return "";
}
}

Change which line in the loop is commented out to see the difference
between casting and not. I've explicitly made sure that the
GetSampleObject() method is always called so that the only difference
in the loop should be the cast.

Using 1,000,000,000 iterations, 3 runs for each version:
Without cast: 3403, 3438, 3401
With cast: 3992, 3866, 3904

Is this likely to be significant in most programs? Absolutely not.
However, it does prove that it's not *free*.



The normal time when casts are used are cases like the one the OP
describes, where the cast *is* required because the compiler can't
infer that the conversion is valid - which is precisely the time at
which execution time casts are required. Very occasionally a cast is
required from a more specific type to a more general type in order to
choose the desired overloaded method, but that's not the common case.

Could you describe situations in which you normally cast, and how they
don't require execution time checking? I suspect if you look at the
casts used in genuine (hand-written) code, almost all of them will
require execution time checking.
 
B

Bob Powell [MVP]

ok, not free but not significant.

Nice and pragmatic!

Thanks Jon.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

Jon Skeet said:
Bob Powell said:
I think that the times type checking is employed at runtime are pretty
infrequent, especially for common cases.

Absolutely not. Almost every time I use a cast, it's for something
which requires an execution time test. The common case is precisely
like the OP's, in my view, and that certainly requires execution time
testing.
I tried the following;

#1 a class cast to an interface

If the class is known to implement the interface at compile-time,
that's redundant. If not, it requires an execution time test.
#2 direct call to the classes implementation
#3 direct call to a class method not used as an interface implementation
#4 call to a derived class cast to a base

No execution time test required here - and no cast required unless
you're trying to affect overloading.
#5 direct call to a derived class method
#6 cast from variable of type object to specific type

And this last one is the important one.
in all cases the compiler worked out the correct info and the IL was
pretty
much the same except for the type of the final object.

To clarify;

#1 object was type a
#2 object was type a
#3 object was type a
#4 object was type aderived
#5 object was of type aderived
#6 object was of type a

The stopwatch times to make 10000 calls to methods that themselves made a
thousand iterations, non optimised, were virtually identical.

While I understand that the circumstance arises occasionally, as a
performance issue, I think the question of casting is a non-starter.

If you're trying to test the cost of casting, why are you also
introducing a method call? I'd also question the value of testing
*redundant* casts - sure, they don't take time at execution time, but
they're also not needed even at compile time.

Here's a test program to *just* test casting as far as possible:

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

class Test
{
static void Main(string[] args)
{
int iterations = int.Parse(args[0]);
Stopwatch sw = Stopwatch.StartNew();

for (int i=0; i < iterations; i++)
{
object x = GetSampleObject();
//string x = (string) GetSampleObject();
}

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static object GetSampleObject()
{
return "";
}
}

Change which line in the loop is commented out to see the difference
between casting and not. I've explicitly made sure that the
GetSampleObject() method is always called so that the only difference
in the loop should be the cast.

Using 1,000,000,000 iterations, 3 runs for each version:
Without cast: 3403, 3438, 3401
With cast: 3992, 3866, 3904

Is this likely to be significant in most programs? Absolutely not.
However, it does prove that it's not *free*.



The normal time when casts are used are cases like the one the OP
describes, where the cast *is* required because the compiler can't
infer that the conversion is valid - which is precisely the time at
which execution time casts are required. Very occasionally a cast is
required from a more specific type to a more general type in order to
choose the desired overloaded method, but that's not the common case.

Could you describe situations in which you normally cast, and how they
don't require execution time checking? I suspect if you look at the
casts used in genuine (hand-written) code, almost all of them will
require execution time checking.

--
Jon Skeet - <[email protected]>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
 
B

Ben Voigt [C++ MVP]

Jon said:
Bob Powell said:
I think that the times type checking is employed at runtime are
pretty infrequent, especially for common cases.

Absolutely not. Almost every time I use a cast, it's for something
which requires an execution time test. The common case is precisely
like the OP's, in my view, and that certainly requires execution time
testing.
I tried the following;

#1 a class cast to an interface

If the class is known to implement the interface at compile-time,
that's redundant. If not, it requires an execution time test.
#2 direct call to the classes implementation
#3 direct call to a class method not used as an interface
implementation #4 call to a derived class cast to a base

No execution time test required here - and no cast required unless
you're trying to affect overloading.
#5 direct call to a derived class method
#6 cast from variable of type object to specific type

And this last one is the important one.
in all cases the compiler worked out the correct info and the IL was
pretty much the same except for the type of the final object.

To clarify;

#1 object was type a
#2 object was type a
#3 object was type a
#4 object was type aderived
#5 object was of type aderived
#6 object was of type a

The stopwatch times to make 10000 calls to methods that themselves
made a thousand iterations, non optimised, were virtually identical.

While I understand that the circumstance arises occasionally, as a
performance issue, I think the question of casting is a non-starter.

If you're trying to test the cost of casting, why are you also
introducing a method call? I'd also question the value of testing
*redundant* casts - sure, they don't take time at execution time, but
they're also not needed even at compile time.

Here's a test program to *just* test casting as far as possible:

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

class Test
{
static void Main(string[] args)
{
int iterations = int.Parse(args[0]);
Stopwatch sw = Stopwatch.StartNew();

for (int i=0; i < iterations; i++)
{
object x = GetSampleObject();
//string x = (string) GetSampleObject();
}

sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static object GetSampleObject()
{
return "";
}
}

Change which line in the loop is commented out to see the difference
between casting and not. I've explicitly made sure that the
GetSampleObject() method is always called so that the only difference
in the loop should be the cast.

Analysis ought to show that the return value is unused and optimize away the
cast. The function itself can't be optimized away because you've specified
NoInlining, of course, and I guess that prevents the JIT from inspecting it
for side effects and removing it, but there's no such barrier to eliminating
storage of the return value, is there?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Object casting 2
GridView question 1
nested gridview 1
RowDataBound trouble 4
GridView question 1
GridView Setting a checkbox 1
GridView edit mode issue 2
trying to access the row.databound 2

Top