|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Question about Value Typesstruct 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 Zachary Turner wrote:
Show quote > Suppose I have a Value Type, implemented as a struct. Example: I suppose that is:> > 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;} public MyValueType Info { get { return m_ValueType; } } Show quote :) That depends on how complex the code of the property is, and how much > } > > > 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? 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 Copying a 16 byte structure performs about the same as copying a > 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. 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. Show quote > 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 > > Copying a 16 byte structure performs about the same as copying a Actually my structure is more like a few hundred bytes. Even then I> 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. 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. Zachary Turner wrote:
Show quote >> Copying a 16 byte structure performs about the same as copying a If it's that big you should consider making it a class instead.>> 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. > 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> 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. 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? Zachary Turner wrote:
>> If it's that big you should consider making it a class instead. I have nothing specific, it's only based on my knowledge on how >> >> 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? 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. |
|||||||||||||||||||||||