Benefits of value types over reference types?

Seeing how new instances of value types are created each time they are passed as arguments, I started thinking of scenarios where using the ref or out keywords can show significant performance improvements.

After a while, it hit me that, although I see a lack of use of value types, I did not know any advantages.
So my question is pretty simple - what is the purpose of creating value types? What do we get by copying the structure, and not just creating a new link to it?

It seems to me that it would be much easier to have reference types, for example, in Java.

Edit:. To clear this up, I don't mean value types smaller than 8 bytes (maximum link size), but the type of values ​​whose size is 8 bytes or more.

For example, a Rectangle structure containing four int values.

+6
source share
6 answers
  • A single-byte value instance takes one byte. The type of link takes up space for the link plus a synchronization block and a table of virtual functions and ...

  • To copy a link, you copy four (or eight) byte links. To copy a four byte integer, you copy a four byte integer. Copying types of small values ​​is not more expensive than copying links.

  • Value types that do not contain references should not be checked by the garbage collector at all. Each link must be tracked by the garbage collector.

+13
source

Link building is not a problem. This is just a 32/64 bit copy. Creating an object is expensive. In fact, creating an object is cheap, but collecting it is not.

Value types are good for performance when they are small and often discarded. They can be used in huge arrays very efficiently. The structure does not have an object header. There are other differences in performance.

Edit: Eric Lippert presented a great example in the comments: "How many bytes does an array of a million bytes occupy if they are value types? How many of them occupy if they are reference types?"

I will answer: if the structure packing is set to 1, such an array will take 1 million and 16 bytes (in a 32-bit system). Using reference types, this will take:

 array, object header: 12 array, length: 4 array, data: 4*(1 million) = 4m 1 million objects, headers = 12 * (1 million) 1 million objects, data padded to 4 bytes: 4 * (1 million) 

And so using value types in large arrays might be a good idea.

+3
source

Value types are usually more efficient than reference types:

  • Link type requires additional memory for reference and dereferencing performance

  • The value type does not require additional garbage collection. He receives the garbage collected along with the instance in which he lives. Local variables in methods are cleared when the method is released.

  • Arrays of value type are effective in combination with caches. (Think of an array of ints compared to an array of instances of type Integer )

+3
source

The gain is displayed if your data is small (<16 bytes), you have many instances and / or you manipulate them a lot, especially when switching to functions. This is because creating an object is relatively expensive compared to creating an instance of a small type. And, as someone else noted, objects must be collected, and this is even more expensive. In addition, very small value types take up less memory than reference type equivalents.

An example of a non-primitive value type in .NET is the Point structure (System.Drawing).

+2
source

Each variable has a life cycle. but not every variable needs flexibility so that your variable performs high, but not managed on the heap.

Value types (Struct) contain their data allocated on the stack or allocated on a line in the structure. Link types (class) store a link to the memory address of the value and are allocated on the heap.

What is the purpose of creating value types? Value types are pretty effective for handling simple data (it should be used to represent immutable types to represent values)

Objects of type value cannot be allocated on the garbage heap, and the variable representing the object does not contain a pointer to the object; the variable contains the object itself.

What do we get by copying the structure, and not just creating a new link to it?

If you copy a structure, C # creates a new copy of the object and assigns a copy of the object to a separate instance of the struct. However, if you copy a class, C # creates a new copy of the object reference and assigns a copy of the link to a separate instance of the class. Structures cannot have destructors, but classes can have destructors.

+1
source

One of the main advantages of value types, such as Rectangle , is that if you have n storage locations of type Rectangle , you can be sure that there are n instances of type Rectangle . If you have a MyArray array of type Rectangle with a length of at least two, then an operator like MyArray[0] = MyArray[1] will copy the fields MyArray[1] into the tags MyArray[0] , but they will continue to refer to different Rectangle instances. If then the line of the operator MyArray[0].X += 4 is executed, which will change the X field of one instance, without changing the X value of any other slot in the array or Rectangle instance. Notice, by the way, that creating an array instantly fills it with writable Rectangle instances.

Imagine that a Rectangle is a type of mutable type. Creating an array of mutable Rectangle instances requires that one of them first evaluate the array and then assign a new Rectangle instance to each element of the array. If you wanted to copy the value of one instance of the rectangle to another, you would have to say something like MyArray[0].CopyValuesFrom(MyArray[1]) [which, of course, would fail if MyArray[0] not populated with a link to the new instance). If you accidentally say MyArray[0] = MyArray[1] , writing to MyArray[0].X will also affect MyArray[1].X . Unpleasant stuff.

It is important to note that in C # and vb.net there are several places where the compiler will implicitly copy the value type, and then act on the copy as if it were the original. This is a very bad language design and has prompted some people to suggest that value types should be immutable (since most situations involving implicit copying only cause problems with mutable value types). Back when compilers were very bad at preventing cases where semantically questionable copies led to broken behavior, such a concept could be reasonable. This should be considered obsolete today, although given that any worthy modern compiler will flag errors in most scenarios where implicit copying will result in fuzzy semantics, including all scenarios where structures are only mutated through constructors, property definition tools, or external assignments for publicly mutable fields, An expression of type MyArray[0].X += 5 is more readable than MyArray[0] = new Rectangle(MyArray[0].X + 5, MyArray[0].Y, MyArray[0].Width, MyArray[0].Height) .

+1
source

Source: https://habr.com/ru/post/908798/


All Articles