F
F
footballer2018-04-11 13:21:00
.NET
footballer, 2018-04-11 13:21:00

Why is it that what is considered an advantage of classes over structs is sometimes presented as a disadvantage?

I wondered why tuples in C# decided to implement based on ValueTuple (struct) and not based on Tuple (class), found this on stackoverflow:
https://stackoverflow.com/questions/41084411/whats...
there is the main answer:

When the .NET language design team decided to incorporate tuples and add syntax sugar to them at the language level an important factor was performance. With ValueTuple being a value type, you can avoid GC pressure when using them because (as an implementation detail) they'll be allocated on the stack.

As mentioned, I propose to make tuple types structs rather than classes, so that no allocation penalty is associated with them. They should be as lightweight as possible.

That is, in the answer they claim that structs are better than classes in terms of performance, tk. no resources are needed for memory allocation on the heap and garbage collection after use.
But they always wrote about classes that they are better than structures in that they are easier to copy or transfer from / to functions, because in this case, you do not need to completely copy the entire instance, but only the link.
Why, then, in the case of explaining why ValueTuple is used for tuples, do they say so unambiguously that this is done to improve performance? What if I need to create a tuple, and then return it to callers along the chain a bunch of times? In this case, there will be a lot of copying, why don't they consider this case?
Although they write further that structures are not always a good choice
Arguably, structs can end up being more costly, because assignment copies a bigger value. So if they are assigned a lot more than they are created, then structs would be a bad choice.

but they immediately add that they are preferred if you need to "build and return"
. So the common pattern would be to construct, return and immediately deconstruct them. In this situation, structs are clearly preferable.

but I don't understand why they consider returning from a struct function a good way (although it's obvious that in this case the struct will be copied)?
Why didn't they make tuples for both types of data (structures and classes)? I could choose myself, create a structure like this:
// res  - это структура
var res = (sum: 0, count: 0);
return res ;

or a class like this:
// res  - это класс
var res = new {sum = 0, count = 0};
return res ;

?
Basically, there are already anonymous classes, i.e. no new syntax is needed, just allow them to be passed from one function to another or returned.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
G
Griboks, 2018-04-11
@Griboks

Let's think logically. For the structure, you need to write data to the stack, copy and return, remove the stack. For the class, you need to allocate space in memory, write a reference to the data on the stack, copy and return the reference, remove the stack, and then also strain the garbage collector.
Question: which is easier? Copy data or copy link + do lots of memory manipulation and garbage collection? Of course, when the size of the link is comparable to the size of the data (just the case of tuples), then it's easier to do all this through the stack, performing an order of magnitude fewer operations. Well, when the size of the data is much larger than the link itself, then, obviously, classes should be used.
ps Pure logic without any deepening into programming and .Net.

F
footballer, 2018-04-11
@footballer

when the size of the link is comparable to the size of the data (just the case of tuples)

but I can make a tuple that will not consist of links, but of structures.
struct VeryBigStructure{
    // тут сотни жирных полей-структур
    VeryBigStructure one;
    ...    
    VeryBigStructure oneHundred;
    public static (VeryBigStructure fitst, VeryBigStructure second) GetTwoVeryBigDataObjects()
    {
        var res = (first: new VeryBigStructure(), second: new VeryBigStructure());
        return res;
    }
}

In this case, you will have to copy and return 2 giant objects, and if the chain of calls and returns is large, then you will have to do this several times.
And if I could return a tuple class, then both giant objects would be boxed into a heap, and only a reference to them would be returned. Isn't that better than copying the same giant objects multiple times from one stack to another?
Well, you need to use classes, but it’s not convenient to return through a tuple, you have to spank a wrapper class. Though one could just allow anonymous objects to be returned.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question