Choosing between immutable objects and structs for value objects - c#

How do you choose between implementing a value object (the canonical example being an address) as an immutable object or a struct?
Are there performance, semantic or any other benefits of choosing one over the other?

There are a few things to consider:
A struct is allocated on the stack (usually). It is a value type, so passing the data around across methods can be costly if it is too large.
A class is allocated on the heap. It is a reference type, so passing the object around through methods is not as costly.
Generally, I use structs for immutable objects that are not very large. I only use them when there is a limited amount of data being held in them or I want immutability. An example is the DateTime struct. I like to think that if my object is not as lightweight as something like a DateTime, it is probably not worth being used as a struct. Also, if my object makes no sense being passed around as a value type (also like DateTime), then it may not be useful to use as a struct. Immutability is key here though. Also, I want to stress that structs are not immutable by default. You have to make them immutable by design.
In 99% of situations I encounter, a class is the proper thing to use. I find myself not needing immutable classes very often. It's more natural for me to think of classes as mutable in most cases.

How do you choose between implementing a value object (the canonical example being an address) as an immutable object or a struct?
I think your options are wrong. Immutable object and struct are not opposites, nor are they the only options. Rather, you've got four options:
Class
mutable
immutable
Struct
mutable
immutable
I argue that in .NET, the default choice should be a mutable class to represent logic and an immutable class to represent an entity. I actually tend to choose immutable classes even for logic implementations, if at all feasible. Structs should be reserved for small types that emulate value semantics, e.g. a custom Date type, a Complex number type similar entities. The emphasis here is on small since you don't want to copy large blobs of data, and indirection through references is actually cheap (so we don't gain much by using structs). I tend to make structs always immutable (I can't think of a single exception at the moment). Since this best fits the semantics of the intrinsic value types I find it a good rule to follow.

I like to use a thought experiment:
Does this object make sense when only an empty constructor is called?
Edit at Richard E's request
A good use of struct is to wrap primitives and scope them to valid ranges.
For example, probability has a valid range of 0-1. Using a decimal to represent this everywhere is prone to error and requires validation at every point of usage.
Instead, you can wrap a primitive with validation and other useful operations. This passes the thought experiment because most primitives have a natural 0 state.
Here is an example usage of struct to represent probability:
public struct Probability : IEquatable<Probability>, IComparable<Probability>
{
public static bool operator ==(Probability x, Probability y)
{
return x.Equals(y);
}
public static bool operator !=(Probability x, Probability y)
{
return !(x == y);
}
public static bool operator >(Probability x, Probability y)
{
return x.CompareTo(y) > 0;
}
public static bool operator <(Probability x, Probability y)
{
return x.CompareTo(y) < 0;
}
public static Probability operator +(Probability x, Probability y)
{
return new Probability(x._value + y._value);
}
public static Probability operator -(Probability x, Probability y)
{
return new Probability(x._value - y._value);
}
private decimal _value;
public Probability(decimal value) : this()
{
if(value < 0 || value > 1)
{
throw new ArgumentOutOfRangeException("value");
}
_value = value;
}
public override bool Equals(object obj)
{
return obj is Probability && Equals((Probability) obj);
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
public override string ToString()
{
return (_value * 100).ToString() + "%";
}
public bool Equals(Probability other)
{
return other._value.Equals(_value);
}
public int CompareTo(Probability other)
{
return _value.CompareTo(other._value);
}
public decimal ToDouble()
{
return _value;
}
public decimal WeightOutcome(double outcome)
{
return _value * outcome;
}
}

Factors: construction, memory requirements, boxing.
Normally, the constructor restrictions for structs - no explicit parameterless constructors, no base construction - decides if a struct should be used at all. E.g. if the parameterless constructor should not initialize members to default values, use an immutable object.
If you still have the choice between the two, decide on memory requirements. Small items should be stored in structs especially if you expect many instances.
That benefit is lost when the instances get boxed (e.g. captured for an anonymous function or stored in a non-generic container) - you even start to pay extra for the boxing.
What is "small", what is "many"?
The overhead for an object is (IIRC) 8 bytes on a 32 bit system. Note that with a few hundred of instances, this may already decide whether or not an inner loop runs fully in cache, or invokes GC's. If you expect tens of thousands of instances, this may be the difference between run vs. crawl.
From that POV, using structs is NOT a premature optimization.
So, as rules of thumb:
If most instances would get boxed, use immutable objects.
Otherwise, for small objects, use an immutable object only if struct construction would lead to an awkward interface and you expect not more than thousands of instances.

I actually don't recommend using .NET structs for Value Object implementation. There're two reasons:
Structs don't support inheritance
ORMs don't handle mapping to structs well
Here I describe this topic in detail: Value Objects explained

In today's world (I'm thinking C# 3.5) I do not see a need for structs (EDIT: Apart from in some niche scenarios).
The pro-struct arguments appear to be mostly based around perceived performance benefits. I would like to see some benchmarks (that replicate a real-world scenario) that illustrate this.
The notion of using a struct for "lightweight" data structures seems way too subjective for my liking. When does data cease to be lightweight? Also, when adding functionality to code that uses a struct, when would you decide to change that type to a class?
Personally, I cannot recall the last time I used a struct in C#.
Edit
I suggest that the use of a struct in C# for performance reasons is a clear case of Premature Optimization*
* unless the application has been performance profiled and the use of a class has been identified as a performance bottleneck
Edit 2
MSDN States:
The struct type is suitable for
representing lightweight objects such
as Point, Rectangle, and Color.
Although it is possible to represent a
point as a class, a struct is more
efficient in some scenarios. For
example, if you declare an array of
1000 Point objects, you will allocate
additional memory for referencing each
object. In this case, the struct is
less expensive.
Unless you need reference type
semantics, a class that is smaller
than 16 bytes may be more efficiently
handled by the system as a struct.

In general, I would not recommend structs for business objects. While you MIGHT gain a small amount of performance by heading this direction, as you are running on the stack, you end up limiting yourself in some ways and the default constructor can be a problem in some instances.
I would state this is even more imperative when you have software that is released to the public.
Structs are fine for simple types, which is why you see Microsoft using structs for most of the data types. In like manner, structs are fine for objects that make sense on the stack. The Point struct, mentioned in one of the answers, is a fine example.
How do I decide? I generally default to object and if it seems to be something that would benefit from being a struct, which as a rule would be a rather simple object that only contains simple types implemented as structs, then I will think it through and determine if it makes sense.
You mention an address as your example. Let's examine one, as a class.
public class Address
{
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
Think through this object as a struct. In the consideration, consider the types included inside this address "struct", if you coded it that way. Do you see anything that might not work out the way you want? Consider the potential performance benefit (ie, is there one)?

What is the cost of copying instances if passed by value.
If high, then immutable reference (class) type, otherwise value (struct) type.

As a rule of thumb a struct size should not exceed 16 bytes, otherwise passing it between methods may become more expensive that passing object references, which are just 4 bytes (on a 32-bit machine) long.
Another concern is a default constructor. A struct always has a default (parameterless and public) constructor, otherwise the statements like
T[] array = new T[10]; // array with 10 values
would not work.
Additionally it's courteous for structs to overwrite the == and the != operators and to implement the IEquatable<T> interface.

From an object modeling perspective, I appreciate structs because they let me use the compiler to declare certain parameters and fields as non-nullable. Of course, without special constructor semantics (like in Spec#), this is only applicable to types that have a natural 'zero' value. (Hence Bryan Watt's 'though experiment' answer.)

Structs are strictly for advances users ( along with out and ref) .
Yes structs can give great performance when using ref but you have to see what memory they are using. Who controls the memory etc.
If your not using ref and outs with structs they are not worth it , if you are expect some nasty bugs :-)

Related

Make answer class a struct?

Usually play around with making games but I'm taking a detour into making a little question and answer app, for educational purposes.
Anyway I have a question class which holds numerous members: the question itself, the answer to the question, an array of possible answers etc. No doubts this should be a class.
My answer class however only holds a string, an Enum and an int id number as shown below:
public class Answer
{
public string Answer { get { return answer;} private set { answer = value; } }
public Answer_Category = Some_Value; // The enum.
public int ID { get { return id; } private set { return id; } }
private string answer;
private int id;
}
Ok so it holds two strings, also the ctor has been out.
So should I be making this a struct? I ask as it seems comparable to making a Vector a struct, being such a small data structure 'n all.
Naturally being a question and answer application the answer class/struct is going to be the subject of a lot of search calls.
IMO this should be a struct - solely because of the size of the structure, haven't played around with C# for some time though so just looking for some clarification.
The decision boils down to whether you want a value type or a reference type. In other words what do you want the assignment operator to mean? If you want assignment to copy the value, use a struct. If you want assignment to take another reference e, use a class.
There are two primary usages cases for structures: for situations where one wishes to conveniently move around aggregations of independent variables (such as the coordinates of a point), or where a small immutable object will often be used in situations where identity is not important (as would be the case with e.g. Decimal or DateTime). Since a variable of structure type simply holds an aggregation of variables, structures which are used for that purpose should simply expose their contents as public fields. Doing so will make clear that any invariants that might be applicable to structure members will be the responsibility of the code creating the structure. For example, if one has a structure MinMax with int members Minimum and Maximum, using exposed public fields for those members would make clear that the structure itself makes no promise that Maximum >= Minimum. A method which returns such a structure may promise that it will not return one where Maximum < Minimum, but methods which receive structures and want Maximum >= Minimum will have to check those fields themselves. On the flip side, code which wishes to set those values in a structure will be able to set them in whatever order is convenient, without having to worry about the struct throwing an exception because the Minimum was set higher than Maximum.
The MSDN guidelines assume that the purpose of any struct is to behave like an object. Since piecewise-mutable structures don't behave like objects, structures which will be used like objects shouldn't be piecewise mutable. On the other hand, aggregations of variables can be useful in and of themselves; one should use a struct in cases where one wants an aggregation of variables, but should try to make it as obvious as possible that the struct is an aggregation of variables rather than an object.

Passing immutable value types by reference by default

Usally I choose between struct and class not because of memory issues but because of semantics of the type. Some of my value types have quite large memory footprint, sometimes too large to copy this data all the time. So I wonder if it is a good idea to pass immutable value objects always by reference? Since the objects are immutable they cannot by modified by methods that accept them by reference. Are there other issues when passing by reference?
Some of my value types have quite large memory footprint
That suggests they shouldn't be value types, from an implementation point of view. From "Design Guidelines for Developing Class Libraries", section "Choosing Between Classes And Structures":
Do not define a structure unless the type has all of the following characteristics:
It logically represents a single value, similar to primitive types (integer, double, and so on).
It has an instance size smaller than 16 bytes.
It is immutable.
It will not have to be boxed frequently.
It sounds like you should be creating immutable reference types instead. In many ways they end up "feeling" like value objects anyway (think strings) but you won't need to worry about the efficiency of passing them around.
"Immutability" for value types is a slightly fluid concept - and it certainly doesn't mean that using ref is safe:
// int is immutable, right?
int x = 5;
Foo(ref x);
Console.WriteLine(x); // Eek, prints 6...
...
void Foo(ref int y)
{
y = 6;
}
We're not changing one part of the value - we're replacing the whole of the value of x with an entirely different value.
Immutability is somewhat easier to think about when it comes to reference types - although even then you can have an object which in itself won't change, but can refer to mutable objects...
Jon's answer is of course correct; I would add this to it: value types are already passed by reference when you call a method on the value type. For example:
struct S
{
int x;
public S(int x) { this.x = x; }
public void M() { Console.WriteLine(this.x); }
}
Method M() is logically the same thing as:
public static void M(ref S _this) { Console.WriteLine(_this.x); }
Whenever you call an instance method on a struct, we pass a ref to the variable that was the receiver of the call.
So what if the receiver is not a variable? Then the value is copied into a temporary variable which is used as the receiver. And if the value is big, that's potentially an expensive copy!
Value types are copied by value; that's why they're called value types. Unless you are planning on being extremely careful about finding all the possible expensive copies and eliminating them, I would follow the framework design guideline's advice: keep structs under 16 bytes, and pass them by value.
I would also emphasize that Jon is right: passing a struct by ref means passing a reference to a variable, and variables can change. That's why they're called "variables". There is no "const ref" in C# the way there is in C++; even if the value type itself seems to be "immutable" that doesn't mean that the variable holding it is immutable. You can see an extreme example of that in this contrived but educational example:
struct S
{
readonly int x;
public S(int x) { this.x = x; }
public void M(ref S s)
{
Console.WriteLine(this.x);
s = new S(this.x + 1);
Console.WriteLine(this.x);
}
}
Is it possible for M to write out two different numbers? You would naively think that the struct is immutable, and therefore x cannot change. But both s and this are variables, and variables can change:
S q = new S(1);
q.M(ref q);
That prints 1, 2 because this and s are both references to q, and nothing is stopping q from changing; it is not readonly.
In short: if I had a lot of data that I wanted to be passing around and have strong guarantees that it was immutable, I'd be using a class, not a struct. Only use a struct in that scenario if you have a demonstrated performance problem that is actually solved by making it a struct, keeping in mind that large structs are potentially very expensive to copy.
So I wonder if it is a good idea to pass immutable value objects always by reference? Since the objects are immutable they cannot by modified by methods that accept them by reference. Are there other issues when passing by reference?
It's not clear exactly what you mean. Assuming that you mean passing it as a ref or out parameter, then the method could merely assign a new instance to the storage location. This would modify what the caller sees because the storage location in the callee is an alias for the storage location passed by the caller.
If you're dealing with memory issues because of copying instances of struct around, you should consider making an immutable reference type, much like string.
I think actually the bad idea is to use structs when everything you do points to use classes
Related answer: https://stackoverflow.com/questions/2440029/is-it-a-bad-practice-to-pass-structs-by-reference

.NET immutable object usage best practices? Should I be using them as much as possible?

Say I have a simple object such as
class Something
{
public int SomeInt { get; set; }
}
I have read that using immutable objects are faster and a better means of using business objects? If this is so, should i strive to make all my objects as such:
class ImmutableSomething
{
public int SomeInt { get { return m_someInt; } }
private int m_someInt = 0;
public void ChangeSomeInt(int newValue)
{
m_someInt = newvalue;
}
}
What do you reckon?
What you depict is not an immutable object; simply moving the set code into a dedicated setter method doesn't make an object immutable. An immutable object, by definition, can't change, so the fact that you can alter the value of any of the object's properties or fields means that it isn't immutable.
In terms of "faster" or "better", immutable objects are not intrinsically faster or "better" than mutable objects; there isn't anything special about them, other than the fact that you can't change any values.
As others have said what you've posted isn't immutable. This is what an immutable object looks like. The readonly keyword means that the only place that the backing field for the property can be set is in the constructor. Essentially, after the object is constructed that's it forever.
public class ImmutableSomething
{
private readonly int _someInt;
public int SomeInt
{
get
{
return _someInt;
}
}
public ImmutableSomething(int i)
{
_someInt = i;
}
public ImmutableSomething Add(int i){
return new ImmutableSomething(_someInt + i);
}
}
This is a big deal in functional programming because instead of talking about objects you get to talk about Values. Values never change, so you know that when you pass them to a function or method your original value will never be changed or updated. With mutable objects you can't make that guarantee.
Code built with immutable objects can be easily parallelized because there is no writable shared state. If some other thread gets your Value and wants to do something to it, it can't. "Changing" it in any way produces a new object with a brand new spot in memory just for that object.
So once you're dealing with values you can do some special things like interning which is what .NET does with strings. Because "Hello World" is a value and will never change, one reference to "Hello World" is just as good as any other, so instead of having "Hello World" in a hundred slots in memory, you have it in one slot and set all the references to "Hello World" to point to that one slot. So you get a big win on the memory side but you pay a performance penalty because whenever you create a new string you have to check the intern pool to make sure it doesn't already exist.
The primary advantage of deeply immutable objects is that it's very easy to take a "snapshot" of their properties--simply copy a reference to the object. No matter how big or complicated the object might be, one can "snapshot" the whole thing simply by copying one reference.
By contrast, if one wants to take a snapshot of a mutable object's properties, it's necessary to copy all of them. If any of those properties are themselves mutable objects, it will be necessary to copy all of those as well. In some cases, making a usable copy of a mutable object's state can be very complicated or even impossible, since objects may have their state intertwined with those of singletons.
Although immutable objects are far easier to "snapshot" than mutable ones, it can sometimes be difficult to, given an immutable object, produce an instance which is similar to the first one except for some minor change. Mutable objects can sometimes be easier to work with in that regard. Sometimes it can be useful to copy data from an immutable object into a mutable object, change it, and then produce a new immutable object which holds the changed data. Unfortunately, there isn't any general means to automate such conversion with classes. There is, however, an alternative.
A struct with exposed fields which are all value primitives or immutable class references can offer a very convenient means of holding information in an immutable object, copying it to a mutable form, modifying it, and then making a new immutable object. Alternatively, one may copy the data in a struct easily by just copying the struct itself. Copying a struct which contains more than one or two int-sized fields is somewhat more expensive than copying an immutable-object reference, but copying a struct and changing it is generally much cheaper than making a new changed immutable object. It's important to note that because of some quirks in the way .net languages handle structs, some people regard mutable structs as evil. I would recommend that in general it's best for structs to simply expose their fields, and avoid having any methods (other than constructors) which mutate this. That will avoid most of the quirks associated with mutable structs, and will often offer better performance and clearer semantics than can be obtained with immutable classes, mutable classes, or so-called immutable (really "mutable by assignment only") structs.
Incidentally, it is sometimes useful to design an immutable object so that producing a slightly-different object will copy everything from the old object to a new one, but with the appropriate part changed, and it is sometimes useful to design an immutable object so that a slightly-different object will be able to "reuse" most of the original object. In many cases, the former approach will be the more efficient one if the object will be read much more often than it is written, and there isn't going to be any need to keep old snapshots around after an object has been changed. The latter approach can be the more efficient one in cases where one will want to keep around many snapshots, and updates are frequent relative to read accesses.
That's not an immutable object. An immutable version of this would be something like
class ImmutableSomething : ISomething
{
public readonly int SomeInt;
public ImmutableSomething(int i)
{
SomeInt = i;
}
public ImmutableSomething AddValue(int add)
{
return new ImmutableSomething(this.SomeInt + add);
}
}
The main benefit of an immutable object is that the object itself will never change, so you don't risk one part of your code changing the underlying values, especially in multithreading situations, but this applies in general. These guarantees often makes objects "better" in that you know what to expect, but there's nothing that makes immutables inherently "faster" than mutable objects.
For example, DateTimes are immutable, so you can do stuff like
DateTime someReferenceTime = DateTime.Now;
myBusinessLayer.DoABunchOfProcessingBasedOnTime(someReferenceTime);
// Here you are guaranteed that someReferenceTime has not changed, and you can do more with it.
Versus something like
StringBuilder sb = new StringBuilder("Seed");
myBusinessLayer.DoStuffBasedOnStringBuilder(sb);
// You have no guarantees about what sb contains here.
Leaving aside the point that the example doesn't actually show an immutable object, the main benefit for immutable objects is that they make certain multi-threaded operations dead simple and lock-free. For example, enumerating an immutable tree structure is possible without locks in a multi-threaded environment, whereas if the tree was mutable, you would need to introduce locks in order to safely enumerate it.
But there is nothing magical about immutable objects that makes them inherently faster.

Structs - real life examples? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
There are any number of questions here on SO dealing with the differences between Structs and Classes in C#, and when to use one or the other. (The one sentence answer: use structs if you need value semantics.) There are plenty of guidelines out there about how to choose one or the other, most of which boil down to: use a class unless you meet these specific requirements, then use a struct.
This all makes sense to me.
However, I can't seem to find any real-life examples of people using structs in a system. I'm (semi-)new to C#, and I'm having trouble imagining a concrete situation where structs are really the right choice (at least, I haven't run into one yet.)
So, I turn to the SO world-brain. What are some cases where you actually used a struct in a system where a class wouldn't have worked?
Well a class would still work for it, but an example I could think of is something like a Point. Assuming it is an x and y value, you could use a struct.
struct Point {
int x;
int y;
}
In my mind, I would rather have a more simple representation of a pair of integers than to define a use a class with instantiations when the actual entity does not really have much(or any) behavior.
I used a struct to represent a Geolocation
struct LatLng
{
public decimal Lattitude
{
get;
set;
}
public decimal Longitude
{
get;
set;
}
}
this represents a single entity, for instance I can add 2 LatLng's together or perform other operations on this single entity.
MSDN-struct
The struct type is suitable for
representing lightweight objects such
as Point, Rectangle, and Color.
Although it is possible to represent a
point as a class, a struct is more
efficient in some scenarios. For
example, if you declare an array of
1000 Point objects, you will allocate
additional memory for referencing each
object. In this case, the struct is
less expensive.
Also if you look at primitive types Int32,decimal,double..etc you will notice they are all structs, which allows them to be value types whilst allowing them to implement certain crucial interfaces.
Structs are also typically used in graphics/rendering systems. There are many benefits to making points/vectors structs.
Rico Mariani posted an excellent quiz on value based programming. He discussed many reasons to prefer structs in specific situations, and explained it in detail in his quiz results post.
A Money struct is probably one of the most common, however Phone number or Address are also common.
public struct Money
{
public string Currency { get; set; }
public double Amount { get; set; }
}
public struct PhoneNumber
{
public int Extension { get; set; }
public int RegionCode { get; set; }
//... etc.
}
public struct FullName
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
Keep in mind though that in .NET your structs should not be larger in memory footprint than 16 Bytes, because if they get bigger the CLR has to allocate additional memory.
Also because structs 'live' on the stack (and not the heap as reference types do) you might consider using structs if you need to instantiate a lot of the same types of objects.
The quintessential example is the frameworks nullable types, such as int?. These use structs so they retain the value semantics of an int, yet providing a way to make them null without boxing and turning them into reference types.
You would use a struct when you don't want to pass something by reference. Suppose you have a collection of data, or an object that you wish to pass by value (ie, anything you pass it to is working with its own unique copy, not a reference to the original version) then a struct is the right type to use.
They provide a default implementation for Object.GetHashCode(), so you might want to use a struct instead of a class when the object is a simple collection of non-reference types that you want to use as keys to a dictionary.
They are also useful for PInvoke/interop or low-level networking scenarios where you want precise control over the binary layout of a data structure. (go to www.pinvoke.net for lots of interop code that requires structs)
But really, I never use them myself. Don't sweat not using them.
Basically I try to NOT use them. I find they confuse other developers on the team and thus are not worth the effort. I have only found one case to use it, a custom Enum-like type we use a code generator to produce from XML.
The key for me is to define if I want to keep reference to the same object.
Which makes sence when struct is part of another entity, but does entity itself.
In the example above with LatLong that makes perfect sence, for example. You need to copy values from one object to another, not keep referensing the same object.
I often use structs to represent a domain model value type that might be represented as an enum, but needs an arbitrary unlimited number of discrete values, or I want it to have additional behavior (methods) that you cannot add to an enum... For example, in a recent project many data elements were associated with a specific calendar Month rather than with a date. So I created a CalendarMonth struct that had methods:
static CalendarMonth Parse(DateTime inValue);
static CalendarMonth Parse(string inValue);
and TryParse( ) method,
static bool TryParse(string inValue, out CalendarMonth outVal);
And Properties
int Month { get; set; }
int Year { get; set; }
DateTime StartMonthLocal { get; set; }
DateTime StartMonthUTC{ get; set; }
DateTime EndMonthLocal { get; set; }
DateTime EndMonthUTC { get; set; }
etc.
im not usually concerned with 'data-density' in my business apps. I will typically always use a class unless I specifically want value semantics
this means that i am forseeing a situation where i want to compare two of these things and i want them to show up as the same if they have the same value. With classes this is actually more work because i need to override ==, !=, Equals, and GetHashcode, which even if resharper does it for me, is extra needless code.
So in my mind, always use classes unless you know that you want these things to be compared by value(in this case component value)
So I take it you've never used DateTime (a struct).
I can't believe no one has mentioned XNA: in XNA, almost everything is a struct. So when you do
Matrix rotation = Matrix.CreateRotationZ(Math.PiOver2);
You are really creating a value-type.
This is because, unlike in applications programming, a stall of a few milliseconds while the garbage collector runs is not acceptable (we only get 16.6 ms to render the entire frame!), so we have to avoid allocations as much as possible so the GC doesn't have to run as much.
This is especially true on the XBox 360, where the GC is nowhere near the quality it is on the PC - even an average of one allocation per frame can kill performance!
I have been working in financial institutions where large scale caching and latency requirements was achieved using structs. Basically structs can spare the garbage collector of A LOT of work.
See these examples:
http://00sharp.wordpress.com/2013/07/03/a-case-for-the-struct/
http://00sharp.wordpress.com/2013/07/04/a-case-for-the-structpart-2/
Basically, I use Structs for modeling geometric and mathematical data, or when I want a Value-based data-structure.
The only time I've ever used a struct was when I was building a Fraction struct:
public struct Fraction
{
public int Numerator {get;set;}
public int Denominator {get; set;}
//it then had a bunch of Fraction methods like Reduce, Add, Subtract etc...
}
I felt that it represents a value, just like the built in value types, and therefore coding against it would feel more natural if it behaved like a value type.
I think the .Net Framework is quite real life. See the list under "Structures":
System Namespace
In some performance-critical situations, a struct (a value type and thus allocated from the stack) can be better than a class (a reference type and thus allocated from the heap). Joe Duffy's blog post "A single-word reader/writer spin lock" shows a real-life application of this.
One I've created in the past is StorageCapacity. It represented 0 bytes to N exabytes (could have gone higher to the yottabyte, but exa seemed enough at the time). The struct made sense since I worked for a storage management company. You would think it was fairly simple: a struct with a StorageUnit (enum) and a Quantity (I used decimal). But when you add in conversions, operators, and classes to support formatting, parsing, etc. it adds up.
The abstraction was useful to enable you to take any StorageCapacity and represent it as bytes, kilobytes, etc. without having to multiply or divide by 1024 many times.
I have given my reasons for using structs already elsewhere (When to use struct in C#), and I have used structs for these reasons in real-life projects:
I would choose to use structs for performance reasons if I needed to store a large number of the same item type in an array, which may happen in image processing.
One needs to use structs for passing structured data between C# and C++.
Unless I have a very good reason to use them I try to avoid them.
I know that some people like to use them for implementing value semantics but I find that this behavior is so different from the "normal" assignment behavior of classes (in C#) that one finds oneself running into difficult to trace bugs because one did not remember that the object one was assigning from or to had this behavior because it was implemented as a struct instead of a class. (It has happened to me more than once, so I give this warning since I actually have been burned by the injudicuous use of C# structs.)
I'm not sure how much use this is, but I discovered today that whilst you cannot have instance field intializers in structs, you can in classes.
Hence the following code will give compilation errors, but if you change the "struct" to "class" it compiles.
public struct ServiceType
{
public bool backEnd { get; set; }
public bool frontEnd { get; set; }
public string[] backEndServices = { "Service1", "Service2" };
public string[] frontEndServices = { "Service3", "Service4" };
}
A struct in C# is at its heart nothing more nor less than a bunch of variables stuck together with duct tape. If one wants each variable of a particular type to represent a bunch of independent but related variables (such as the coordinates of a point) stuck together with duct tape, it's often better to use an exposed-field struct than a class, regardless of whether "bunch" means two or twenty. Note that although Microsoft's struct-versus-class advice is fine for data types which encapsulate a single value, it should be considered inapplicable for types whose purpose is to encapsulate independent but related values. The greater the extent to which the variables are independent, the greater the advantages of using an exposed-field struct.
If one wishes to use a class to encapsulate a bunch of independent variables, there are two ways one can do it, neither of which is terribly convenient. One may use an immutable class, in which case any non-null storage location of that class type will encapsulate the values held by the instance identified thereby, and one storage location may be copied to another to make the new one encapsulate those same values. Unfortunately, changing one of the values encapsulated by a storage location will generally require constructing a new instance which is just like the old one except with that value changed. For example, if one has a variable pt of type Immutable3dPoint and one wished to increase pt.X by one, one would have to do something like: pt = new Immutable3dPoint(pt.X+1, pt.Y, pt.Z); Perhaps tolerable if the type only encapsulates three values, but pretty annoying if there very many.
The other class-based approach is to use a mutable class; this generally requires that one ensure that every storage location of the class type holds the only reference anywhere in the universe to an instance of that class. When a storage location is created, one must construct a new instance and store a reference there. If one wishes to copy the values from storage location P to storage location Q, to another, one must copy all the fields or properties from one instance to the other (perhaps by having the type implement a CopyFrom method, and saying Q.CopyFrom(P);. Note that if one instead says Q=P; that may seem to work, but future attempts to modify P will also modify Q and vice versa. Mutable classes may work, and they can at times be efficient, but it's very easy to mess things up.
Exposed-field structures combine the convenient value-copy semantics of immutable classes with the convenient piecewise modifications allowed by mutable classes. Large structures are slower to copy than are references to immutable objects, but the cost of modifying part of an exposed-field structure depends only upon the extent of the modification, rather than upon the overall structure size. By contrast, the cost of changing one piece of data encapsulated in an immutable class type will be proportional to the total class size.

Struct vs Class for long lived objects

When you need to have very small objects, say that contains 2 float property, and you will have millions of them that aren't gonna be "destroyed" right away, are structs a better choice or classes?
Like in xna as a library, there are point3s, etc as structs but if you need to hold onto those values for a long time, would it pose a performance threat?
Contrary to most questions about structs, this actually seems to be a good use of a struct. If the data it contains are value types, and you are going to use a lot of these, a structure would work well.
Some tips:
:: The struct should not be larger than 16 bytes, or you lose the performance advantages.
:: Make the struct immutable. That makes the usage clearer.
Example:
public struct Point3D {
public float X { get; private set; }
public float Y { get; private set; }
public float Z { get; private set; }
public Point3D(float x, float y, float z) {
X = x;
Y = y;
Z = z;
}
public Point3D Invert() {
return new Point3D(-X, -Y, -Z);
}
}
The answer depends on where the objects/values will eventually be stored. If they are to be stored in an untyped collection like ArrayList, then you end up boxing them. Boxing creates an object wrapper for a struct and the footprint is the same as with a class object. On the other hand if you use a typed array like T[] or List, then using structs will only store the actual data for each element with footprint for entire collection only and not its elements.
So structs are more efficient for use in T[] arrays.
The big concern is whether the memory is allocated on the stack or the heap. Structs go in the stack by default, and the stack is generally much more limited in terms of space. So creating a whole bunch of structs just like that can be a problem.
In practice, though, I don't really think it's that big of a deal. If you have that many of them they're likely part of a class instance (on the heap) somewhere.
Struct seems right for this application.
Bear in mind that the "need to hold onto those valueS" implies their storage on the heap somewhere, probably an array field of a class instance.
One thing to watch out for is that this results in a allocation on the large object heap. Its not that clear how, if at all, this heap defrags itself, however for very long lived objects that perhaps isn't an issue.
Using class for millions of these data types would likely be expensive in the shear volume of dereferencing that will likely be taking place for operations on this type.
As a rule, large arrays of non-aliased (i.e. unshared) data of the same type is best stored in structs for performance since you reduce the number of indirections. (See also when-are-structs-the-answer). The exact performance difference between class and struct depends on your usage. (E.g., in operations, do you only access parts of the struct? Do you do a lot of temporary copying? If the struct is small it's probably always better to use but if it's large, creating temporary copies may slow you down. If you make it immutable you will have to always copy the whole thing to change the value.)
When in doubt, measure.
Since you are interested in possible long-term effects that may not be apparent by such a measurement, be aware that such arrays are likely stored on the large-object heap and should be re-used instead of destroyed and re-allocated. (see CRL Inside Out: Large Object Heap Uncovered.)
When passing larger-size structs in calls you might want to pass them with the ref argument to avoid copying.
Value types (struct) are good for type that are not allocated on heap often, that is, they are mostly contained in another reference or value type.
The Vector3 example you gave is a perfect example. You will rarely have dangling Vector3 in heap, they will most of the time be contained in a type that is itself in heap, or used as a local variable, in which case, it will be allocated on the stack.

Categories