Reputation: 8813
How much performance gain could be achieved using struct over class? Should I design the apps focusing the maximize use of struct over class?
Can I convert my classes into struct and move functions into another static classes wherever it's possible?
Upvotes: 8
Views: 7998
Reputation: 11101
The msdn recommendations (listed in another answer) offers some guidance. For performance you should consider their usage and where the difference between structs and classes matter. The most important thing is to only use structs when the type is an actual value type, i.e. has value semantics. Using a class for a value type, or a struct for something that should be a reference type will quickly give confusing results with unintened copying or unintended references. Also remember that structs should always be immutable.
Only in extremely performance-sensitive situations should you ignore any of these basic rules (Case in point: The framework breaks the rules for the List.Enumerator structure!).
Perf considerations for structs vs classes:
If you pass your struct as an argument to a method, you will create a copy of the struct each time. This is why the docs recommend not making structs larger than 16 bytes.
double Distance(Vector3D a, Vector3D b) // Copies both 24-byte structs
{
return Math.Sqrt((a.X - b.X *....);
}
In the scenario above, a 3D vector of 3 doubles would make 24 bytes and would be larger than the recommended 16, but I'd still argue that a struct makes sense since it is clearly a value type, especially you have a Vector2D containing two doubles (16 bytes) that is a struct!
The key to using structs efficiently, and where their performance really shines, is to use them for cache locality and avoiding many allocations. To re-use the Vector example above, if you have this method
double AverageDistanceFromOrigin(Vector3D[] points) // Single reference passed
{
double sum = 0.0;
for(...)
sum += Math.Sqrt(points[i].X... + ... + ...) // No copies
return sum/points.Length;
}
You may see a good performance difference in favor of structs. The reason is that now you are passing a single reference (the array) to the method, so there is no extra overhead for copying the struct per call(Note that the method does not call a distance-method for each entry in the array).
The array-of-structs is also laid out consecutively in memory like [x1, y1, z1, x2, y2, ...] so the cpu will load e.g. 16 coordinates at a time into the cache , leading to few cache misses. Compare that to a class Vector3D
implementation: now an array of vectors will be allocated and each entry in the array will also be a reference that has to be heap allocated, and later garbage collected. The array is now an array of references [ref to v1, ref to v2, ref to v3] each of which may have any address in the heap, and may not sit next to eachother. This can lead to many more cache misses than the struct case.
Upvotes: 14
Reputation: 1101
Converting your structs to classes will not automatically improve the performance of your application.
It depends on how you use them, vs how you used your class objects.
If you create and destroy alot of objects of a class, you can either reuse an object of that class, or create a struct and reuse it too
(so you see, you could do that with a class too).
When you call a method and send parameters or return a value,
a class is passed by reference, and a struct is passed by value.
So here you might enjoy performance gain, if you pass it alot of time.
(yet again, with good programming you can even avoid passing it all the time to the method, by making the data as a field(s) of the class that contains the methods).
Regarding your second question,
you can have methods inside a struct too, you don't necessarily need to move them to a static class.
struct SimpleStruct
{
private int xval;
public int X
{
get
{
return xval;
}
set
{
if (value < 100) xval = value;
}
}
public void DisplayX()
{
Console.WriteLine("The stored value is: "+xval);
}
}
https://msdn.microsoft.com/en-us/library/aa288471.aspx
Upvotes: 0
Reputation: 113242
How much performance gain could be achieved using struct over class?
For "could be" the answer would be that you could many times faster.
However it could also be many times slower.
Most of the time it'll be neither, but just give a slight gain or loss.
So "I'll use structs to be faster" is, on its own, wrong-headed thinking.
If your starting point is to consider whether something should be a ValueType
because it should indeed be a value-type; defined, used and reasoned-about solely in terms of its value, or should not be a ValueType
because it is not such a value-type, then you're likely going to have the most performant choice for that particular case a good 95% or more of the time.
Of the remaining 5%, probably 90% of those will only be negligibly less performant if you'd gone the other way, and/or they just won't be in hot enough paths for it to matter. (Say you save 20 milliseconds on a given method. If that method is called a million times then you've saved five and a half hours of run time, but if it's called once you've saved 20 milliseconds you won't even notice).
Of the cases where we would actually want to change between value and reference types for performance reasons, we might very often go from struct
to class
rather than the other way around. Indeed so much so that avoiding value types being much over 16 bytes in size is an oft-cited guideline though really that's a performance optimisation rather than an inherent part of what it means to be a value or reference type.
It's also worth noting the differences in value and reference types by calling code. There are some operations that can be much quicker on arrays of mutable structs than on arrays (or any other collection) of mutable reference types. But taking advantage of those requires that you both make the fields public and the value-types mutable; both things that can cause considerable difficulties. Such optimisations are reasonable for private
types within a class that uses them, and at a push for internal
types, but if done with public
types it's asking for trouble.
Upvotes: 1
Reputation: 172428
The MSDN has good points to that:
✓ CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.
X AVOID defining a struct unless the type has all of the following characteristics:
- It logically represents a single value, similar to primitive types (int, double, etc.).
- It has an instance size under 16 bytes.
- It is immutable.
- It will not have to be boxed frequently.
Also the MSDN has Struct Design
Should I design the apps focusing the maximize use of struct over class?
It depends on to what you are trying to implement. Structs are used when you have a small structures which you are trying to implement which will behave like values. So saying that using struct over class is not a ideal statement or approach.
Upvotes: 11
Reputation: 680
Well the short answer is "You can, but you shouldn't".
The main difference between classes and structures is that a structure defines a Value type, while a class defines a reference type. Therefore you can't actually just replace the "class" word with "struct" and move the functions, because the behavior of your program could be heavily affected by the above mentioned difference. Then, if you are designing a new application from scratch yes you can consider whether to define your logical objects using structures or classes where it is appropriate, but then your code has to keep that in mind. I hope this helps!
Upvotes: 3