@footballer

Почему то, что считается преимуществом классов над структурами, иногда выставляется недостатками?

Я подумал, почему кортежи в C# решили реализовать на основе ValueTuple (структуры) , а не на основе Tuple (класса), нашел это на стэковерфлоу:
https://stackoverflow.com/questions/41084411/whats...
там главный ответ:
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.

То есть, в ответе они утверждают, что структуры лучше, чем классы, с точки зрения производительности, т.к. не нужно ресурсы на аллокацию памяти в куче и сборку мусора после использования.
Но всегда про классы писали, что они они лучше структур тем, что их проще копировать или передавать из\в функции, т.к. в этом случае не нужно полностью копировать весь экземпляр, а только ссылку.
Почему тогда в случае с объяснением, почему для кортежей юзается ValueTuple, они так однозначно говорят, что это сделано для улучшения производительности? А если мне нужно создать кортеж, а потом вернуть его вызывающим функциям по цепочке кучу раз? В этом случае будет куча копирований, почему они этот кейс не рассматривают?

Хотя дальше они пишут, что не всегда структуры - хороший выбор
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.

но тут же добавляют, что они предпочтительны, если нужно "построить и возвратить"
. So the common pattern would be to construct, return and immediately deconstruct them. In this situation structs are clearly preferable.

но я не понял, почему возврат из функции структуры они считают хорошим способом (хотя очевидно же, что в этом случае структура будет копироваться)?

Почему не сделали кортежи для обоих видов данных (структур и классов)? Я бы мог сам выбирать, создавать структуру так:
// res  - это структура
var res = (sum: 0, count: 0);
return res ;

или класс так:
// res  - это класс
var res = new {sum = 0, count = 0};
return res ;

?
По сути, уже есть анонимные классы, т.е. новый синтаксис не нужен, просто нужно позволить передавать их из одной функции в другую или возвращать.
  • Вопрос задан
  • 417 просмотров
Пригласить эксперта
Ответы на вопрос 2
Griboks
@Griboks Куратор тега C#
Давайте поразмыслим логически. Для структуры необходимо записать данные на стек, скопировать и вернуть, удалить стек. Для класса необходимо выделить место в памяти, записать ссылку на данные на стек, скопировать и вернуть ссылку, удалить стек, а потом ещё и напрячь сборщик мусора.

Вопрос: что проще? Скопировать данные или скопировать ссылку+произвести множество манипуляций с памятью и сборкой мусора? Безусловно, когда размер ссылки сравним с размером данных (как раз случай кортежей), то проще всё это сделать через стек, совершая на порядок меньше операций. Ну а когда размер данных много больше самой ссылки, то тут, очевидно, надо использовать классы.

p.s. Чистая логика без каких-либо углублений в программирование и .Net.
Ответ написан
Комментировать
@footballer Автор вопроса
когда размер ссылки сравним с размером данных (как раз случай кортежей)

но я могу сделать кортеж, который будет состоять не из ссылок, а из структур.
struct VeryBigStructure{
    // тут сотни жирных полей-структур
    VeryBigStructure one;
    ...    
    VeryBigStructure oneHundred;
    public static (VeryBigStructure fitst, VeryBigStructure second) GetTwoVeryBigDataObjects()
    {
        var res = (first: new VeryBigStructure(), second: new VeryBigStructure());
        return res;
    }
}

В этом случае придется копировать и возвращать 2 гигантских объекта, а если цепочка вызовов и возвратов большая, то делать это придется несколько раз.
А в случае, если бы я мог вернуть кортеж-класс, то оба гигантских объекта бы забоксились в кучу, а возвращалась бы только ссылка на них. Это же лучше, чем по несколько раз копировать одни и те же гигантские объекты из одного стека в другой?

Ну а когда размер данных много больше самой ссылки, то тут, очевидно, надо использовать классы.

Ну вот, надо использовать классы, но удобно вернуть через кортеж не получится, придется шлепать класс-обертку. Хотя можно было бы просто разрешить возвращать анонимные объекты.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы