Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# struct vs Class performace, Design focus

Tags:

c#

class

struct

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?

like image 603
Kylo Ren Avatar asked Dec 18 '15 10:12

Kylo Ren


2 Answers

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.

  • Use structs only if your type has value semantics (and vice versa).
  • Don't pass large structs individually to methods; Operate on lists/arrays of structs to avoid copying
  • Don't consider the 16-byte limit as a hard limit: you can use much larger structs, but remember to avoid passing them individually to methods.
like image 128
Anders Forsgren Avatar answered Oct 02 '22 08:10

Anders Forsgren


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:

  1. It logically represents a single value, similar to primitive types (int, double, etc.).
  2. It has an instance size under 16 bytes.
  3. It is immutable.
  4. 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.

like image 20
Rahul Tripathi Avatar answered Oct 02 '22 09:10

Rahul Tripathi