tags:

views:

231

answers:

5

I know that boxing is a popular concept with plenty of information available on it, but I have a few questions which I can't really find answers to:

1) If boxing leads to a value type (struct) being converted to an object (Reference type), or reference type, then why use a value type which will be boxed and incur a performance penalty? I am aware of the benefits and suitability in certain cases of either a struct or class. It is said (1) that values (value types) tend to live on the stack in a temporary storage space, but how long for? If I don't need the type, how can I ensure it is taken care of and disposed at that moment? Or is this where the disposable pattern comes into play? I assume the reason to use a struct will be due to its benefits.

Interestingly, if I use a struct to store two strings and a DateTime field, the struct will hold two references (strings) and the DateTime together. I obviously assume this is quicker than the values being scattered. Is there anything I need to be aware of in this design? (2).

1) http://en.csharp-online.net/Classes, Structs, and Objects—Boxing and Unboxing

2) http://dotnetperls.com/Content/Struct-Examples.aspx

I have done a search on here for the answers I am after, but no luck. I usually do searches on this site for topics such as GC, generics, exception handling, etc, as there is a lot of wisdom to learn and share.

Thanks for the (potential) education to all posters! Please excuse any potential naivety. Learning the internals takes me nicely to spending some time on understanding IL, etc (something to tackle, soon).

+1  A: 

The .NET guidelines for this type of thing might help clear up how you think of them.

There's also an SO thread explaining boxing/unboxing.

Ben S
+1  A: 

You should use value types because of their logical benefit, not the performance gains. That being said, because value types are managed on the stack, do not need to participate in garbage collection. If you have a type that is constantly created and discarded (like an int, float, double, etc), then you can get a good boost by turning these into structs. The thing to be careful of is that you should only really consider this if you can also make the struct immutable.

Michael Meadows
What is required to make a struct immutable? Am I right in thinking just give it a low visibility and make it readonly?
dotnetdev
Also, how does disposal work for value types on the stack anyway?
dotnetdev
Unfortunately, there are no semantics in C# for creating immutable types. It's simply a matter of making sure that its state cannot be changed after creation.
Michael Meadows
Since value types are created on the stack, they are not "allocated" so do not need to be "collected." They simply take up space in the stack for the block it is in scope of. When the block is popped from the stack, the variable no longer takes up memory.
Michael Meadows
+4  A: 

If you never pass the value type into a reference variable then boxing will not occur. When you don't know then answer the following questions:

  • Act like primitive types.
  • Have an instance size under 16 bytes.
  • Are immutable.
  • Value semantics are desirable.

I also usually consider what is the lifetime of such a variable. If it is a local variable used within a method then I would tent to use struct (otherwise class).

David Pokluda
These are taking from the .NET guidelines and are generally good questions to ask yourself.
Ben S
I always hear about wanting value semantics - what would be a time such a thing is desired?
dotnetdev
http://msdn.microsoft.com/en-us/library/aa664472%28VS.71%29.aspx Talks about value semantics and when they are useful.
Ben S
Also, if I use a variable in the scope of a method and it is a class, should I wrap it in a struct?
dotnetdev
If the variable is a primitive, there's no point since those have value semantics already. If the variable is an object that has the four above qualities, it might be a good candidate to turn into a struct rather than an object.
Ben S
I actually meant for an existing .NET type, which is an object but may be a candidate for treatment as a struct.
dotnetdev
The .NET types are usually set to the correct reference vs value type for their most common uses. Wrapping one you just add another layer and make your code more confusing.
Ben S
Ok thanks for telling me that!:)
dotnetdev
A: 
Klinger
+1  A: 

A couple other things to consider -

First, you want to make sure structs are immutable (in general). Because of this, it's a good rule of thumb to not have structs containing reference types. Strings can be an exception to this since they're immutable in C#, but in terms of a general-purpose rule of thumb for design, I'd be wary of this.

Second, there's another use case for structs that wasn't mentioned so far - large numbers of small objects. If you have a large list or array of small objects, structs provide dramatically better cache coherency, and are absolutely critical. This is why most 3D engines use structs for points/vectors - they tend to have large arrays of points for vertices, etc.

This is something worth paying attention to if performance is an important part of your application. For example, in one of my apps, changing a single type from a class to a struct shaved 40% off a long running (>5 minute runtime) process. Having the objects close together in memory if you are using them repeatedly in heavy math computations can provide huge gains.

Now - in your case, having 2 strings and a DateTime probably won't see any improvements from this. The type of routines that would work on strings are probably not doing heavy computation (hopefully), ie: transforming a half a million points in space, or doing a large matrix solution, etc.

Finally - you'll notice that .net3.5sp1 made structs much more useful. Prior to 3.5sp1 (on x86), there was no inlining of methods with struct calls. This limited the performance gains possible via structs. Updating your framework can make old struct code much, much faster (in certain cases).

Reed Copsey
If I look at what types are value and which are reference, then a struct would work a select few value types and all the work with reference types happening in classes. So reference types (bar string) are immutable?
dotnetdev
Basically, but the other way around - Reference types are normally mutable types - ie: properties change their values (set).Structs, on the other hand, would be immutable. Basically, once a struct is constructed, you never want it to change. If you want a new value, you make a new struct.
Reed Copsey