In C #, when is a reference type more efficient than a value type?

Is there a time during which a reference type is more efficient than a value type? What for? Can you give me an example?

+2


source to share


5 answers


Every time you are going to transfer it between many objects.

Every call to a method with a value type, or every time it is assigned to a different location, requires a complete copy of the elements of the value type. If you have quite a lot of members, this can lead to a huge loss in productivity.

For example, let's say you have an object with 20 int values:



public class MyClass { int a; int b; int c; ... }
public class MyStruct { int a; int b; int c; ... }

      

If we do this:

MyClass class = new MyClass();
MyClass struct = new MyStruct();

this.CallSomeMethod(class); // Just copies one IntPtr reference!
this.CallSomeMethod(struct); // Needs to copy a large amount of data to run - 20x the other on x86, 10x on x64, since it 20 Int32 values!

      

+10


source


The question is too broad to have a definite answer. As an example, you can specify where you have a 10k object and pass it to a recursive function. If you use a value type, every time you call a method, you will copy the whole thing.



+4


source


The Value Type element can be accessed without an additional level of indirection. In general, reference types are a good point of view. You should profile your application, and if you run into serious performance issues referencing members, you can try using value types if they are applicable by design.

For very small structures, you may prefer non-profiling value types. Especially if your strct only contains four byte values ​​or something like that. On 64-bit platters, each link (indirection) costs 8 bytes of memory. Be aware that upcoming x64 versions of Windows may store 8 bytes in the CPU register. If your structure is 8 bytes, it can be held in a register.

As already posted, remember that value types must be completely copied to call by value. If your structures are much larger than 8 bytes, this can have a huge performance impact.

0


source


If by efficiency we mean fewer instructions for the CPU, then:

  • Value types have a default constructor that initializes the default value, and reference types have a null reference by default.

  • Changing the value of one value type does not affect the other value type; changing the value of a reference type can change the value of other reference types.

0


source


I try to think more about semantics rather than performance, if I don't have a profile there really is a problem there. So if I want something that behaves like a value and has value semantics, then I use a struct, otherwise I use a class.

I believe this works fine most of the time, as if your object is complex enough for performance to be an issue, you probably don't want the semantics of the value anyway.

0


source







All Articles