Question about Value Types

Z

Zachary Turner

Suppose I have a Value Type, implemented as a struct. Example:

struct MyValueType
{
int Field1;
int Field2;
}

Now, this Value Type is a member variable of a reference type with a
property get accessor. Example:

class MyClass
{
private MyValueType m_ValueType;

public MyValueType Info { get m_ValueType;}
}


Now, in some other function somewhere I do somethign liek this:

MyClass class = new MyClass();
int i = class.Info.Field1;
i = class.Info.Field2;


What are the implications of these 2 lines of code from a performance
standpoint? Does it copy the entire value type onto the stack twice?
Or is it smart enough to only do it once? Or maybe it uses a different
paradigm altogether, since I come from a C++ background I guess there
are many things that seem "intuitive" about how unmanaged code would do
things that no longer apply in the managed world. My concern is that I
might have a severe performance penalty when repeatedly accessing a
value type like this.

At the lowest level, what I am doing is calling unmanaged code to
populate the fields of a struct. So naturally this needs to be a value
type. What is the "general" way to handle this? An obvious
alternative is to create two versions of this object - a reference type
version and an value type version. Use the value type for the interop
only, and marshal data between value/reference types before and after
calling the unmanaged code. Then I would work with reference types
only, perhaps making more efficient code. Or the way I am doing it
now, which is to use the value types throughout my code.

Suggestions? Any insight is appreciated.

Zach
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Zachary said:
Suppose I have a Value Type, implemented as a struct. Example:

struct MyValueType
{
int Field1;
int Field2;
}

Now, this Value Type is a member variable of a reference type with a
property get accessor. Example:

class MyClass
{
private MyValueType m_ValueType;

public MyValueType Info { get m_ValueType;}

I suppose that is:

public MyValueType Info { get { return m_ValueType; } }

:)
}


Now, in some other function somewhere I do somethign liek this:

MyClass class = new MyClass();
int i = class.Info.Field1;
i = class.Info.Field2;


What are the implications of these 2 lines of code from a performance
standpoint? Does it copy the entire value type onto the stack twice?
Or is it smart enough to only do it once?

That depends on how complex the code of the property is, and how much
work the compiler will put into trying to optimize things like that.

It's plausible that the compiler might be able to recognise that the
value returned from the Info property would be the same both times. On
the other hand, it might not want to do this assumption, as
optimizations like that can potentially break code.

If you for an example have a loop that is waiting for a value to be
changed by a different thread:

while (watcher.CheckStatus) { Thread.Sleep(100); }

(Yes, not very good code, but it's just an example.)

If the compiler would make the assumption that the value can't change,
as there is no code in the loop to change it, it could optimize the code to:

bool temp = watcher.CheckStatus;
while (temp) { Thread.Sleep(100); }

That would of course send your application into an eternal slumber.
Or maybe it uses a different
paradigm altogether, since I come from a C++ background I guess there
are many things that seem "intuitive" about how unmanaged code would do
things that no longer apply in the managed world. My concern is that I
might have a severe performance penalty when repeatedly accessing a
value type like this.

Copying a 16 byte structure performs about the same as copying a
reference (according to Microsoft). As long as the structure isn't
substantially larger than that, you don't have to worry unless you are
making some extreme optimization of a tight loop.
 
Z

Zachary Turner

Copying a 16 byte structure performs about the same as copying a
reference (according to Microsoft). As long as the structure isn't
substantially larger than that, you don't have to worry unless you are
making some extreme optimization of a tight loop.

Actually my structure is more like a few hundred bytes. Even then I
realize that optimizing it will provide little to no performance gain,
but I feel dirty when I know that I haven't written the best possible
code. I think I'll do some kind of optimization, my choices are
mirroring the structure in a reference type, or simply returning an
object and letting CLR box and unbox my value type. The first has the
advantage that it makes clean code and avoids unnecessary casting, the
second has the advantage that it doesn't require me to maintain the
definitions for two separate UDTs.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Zachary said:
Actually my structure is more like a few hundred bytes. Even then I
realize that optimizing it will provide little to no performance gain,
but I feel dirty when I know that I haven't written the best possible
code. I think I'll do some kind of optimization, my choices are
mirroring the structure in a reference type, or simply returning an
object and letting CLR box and unbox my value type. The first has the
advantage that it makes clean code and avoids unnecessary casting, the
second has the advantage that it doesn't require me to maintain the
definitions for two separate UDTs.

If it's that big you should consider making it a class instead.

It should be possible to marshal the data area of the object so that it
appears to be a struct to the unmanaged code.
 
Z

Zachary Turner

If it's that big you should consider making it a class instead.

It should be possible to marshal the data area of the object so that it
appears to be a struct to the unmanaged code.

If this is actually possible then that's clearly the best solution. Do
you have any advice how I might go about doing this? I'm a little new
to .NET in general, so I haven't seen all the backdoors and things lke
that yet. I assume this makes some use of attributes similar to the
MarshalAs attribute?
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Zachary said:
If this is actually possible then that's clearly the best solution. Do
you have any advice how I might go about doing this? I'm a little new
to .NET in general, so I haven't seen all the backdoors and things lke
that yet. I assume this makes some use of attributes similar to the
MarshalAs attribute?

I have nothing specific, it's only based on my knowledge on how
references and pointers work.

As you are populating the struct, you have to send a pointer to the
struct to the method that populates it. I don't think that it should be
more complicated than replacing that pointer with a pointer to the
object you want to populate.
 

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

Top