2013-09-27 2 views
0

Имея все знания, которыми владею в этот самый момент, я не могу решить, для чего я буду использовать для своего случая использования.Структура или классы для данного конкретного случая

Это теперь пример со структурой.

Первый класс выглядит следующим образом:

class Owner 
{ 
    public A[] Kids; 

    public Owner(int count) 
    { 
    Kids = new A [count]; 

    // If I would use classes I would need to create new class for each item, right? 
    // It would look like below and my worries are memory impacts because of new A() 
    // for(int i = 0; i < count; Kids[i++] = new A()); 
    } 
} 

Второй класс выглядит следующим образом:

class Node 
{ 
    private Owner o; 
    private int num; 
    private A[] kids; 

    public Node(Owner o, int num) 
    { 
    this.o = o; 
    this.num = num; 
    } 

    public A[] Kids 
    { 
    get 
    { 
     this.kids = o.Kids[num].NextList; 
     return this.kids; 
    } 
    } 
} 

типа А выглядит эта

<struct or class> A 
{ 
    public int Value; 
    public A[] NextList; 
} 

Вопрос теперь, когда используя structs, доступ будет работать быстрее, чем при использовании классов?

Могу ли я получить издержки памяти при использовании классов, так как мне нужно будет инициализировать каждый класс.

Должен ли я позаботиться о том, чтобы убивать ссылки при использовании классов?

Что вы будете использовать для этого в этом случае?

Прошу прощения, если это дубликат, или если я сделал что-то неправильно. Пожалуйста, скажите мне, что я сделал не так, прежде чем понизить этот вопрос. Я еще новичок в этом форуме.

+0

ли 'A' когда-либо мутировали, или он используется в качестве неизменного моды? Что касается вашего вопроса о ссылках, все, что вам нужно сделать, это «отпустить» их, чтобы они имели право на сбор мусора. Я склонен найти классы более чем адекватными даже в ситуациях, когда структуры могут быть немного лучше. В настоящее время у меня все меньше и меньше причин, чтобы беспокоиться о «структурированном» материале. –

+3

Я думаю, что вы переоцениваете влияние использования классов. Я бы предложил вам выбрать тот, который имеет наибольший смысл и касается только проблем с производительностью по мере их возникновения. Как однажды сказал Дональд Кнут: «Преждевременная оптимизация - это корень всего зла». Если вы действительно обеспокоены оптимизацией этого, я бы это прокомментировал. Проверьте оба сценария и измерьте время. – Moeri

+0

Существует множество дебатов о преимуществах использования классов или структур, я несколько дней назад был отклонен за предложение использовать структуру, чтобы я мог понять вашу нервозность. Я думаю, что ответ будет чем-то вроде «зависит» и от многих факторов. Обычно я использую классы, но я подозреваю, что фактическая разница незначительна. – bhs

ответ

1

TL; DR: Используйте класс.

Поскольку вы используете массив, и вы беспокоитесь о памяти, есть одна вещь, чтобы иметь в виду:

Если у вас есть массив структур, то общее количество байтов, выделенных для массива будет sizeof(your struct) * number of elements

Если у вас есть массив классов, то общие байты, выделенные для массива, будут sizeof(reference) * number of elements (где размер ссылки 32 бит для x86 и 64 бит для x64).

Этот может сделать большую разницу в некоторых случаях.

Если общий размер массива превышает 85 000 байт, он будет помещен в кучу больших объектов. В противном случае он переходит в обычную кучу. Это может означать, что использование структуры приведет к тому, что некоторые из ваших массивов превысят порог в 85 000 байт, в то время как они не достигнут этого порога, если вы использовали класс вместо этого.

Элементы большой кучи объекта не уплотняются во время сбора мусора (*), поэтому вы можете получить проблемы с фрагментацией памяти, если у вас слишком много больших объектов.

Обратите внимание, что это также относится ко многим другим коллекциям (например, List<T>), поскольку они используют массив в своей реализации.

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

Следовательно, вы должны просто использовать класс.

Существует еще одна вещь, чтобы быть в курсе:

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

Так что это не представляется возможным:

List<MyStruct> list = new List<MyStruct>(); 
... init list 
list[0].Value = 1; // Compile error for structs, no error for classes. 

Это не должно быть проблемой, хотя - потому что ваши структуры являются всегда неизменны, так что вы бы не попытаться сделать это в первую очередь, не так ли? ;)


(*) Это не совсем верно. .Net 4.51 вводит способ разрешить следующей сборке мусора перемещать большие объекты, но это должно быть программно спровоцировано.

http://blogs.msdn.com/b/mariohewardt/archive/2013/06/26/no-more-memory-fragmentation-on-the-large-object-heap.aspx

+0

У меня нет списка структур, просто массивов. Как вы можете видеть в моем примере, учитывая, что класс Node содержит Kids. Если я сделаю эту структуру, мне бы не хотелось выпускать ссылку, верно ?. Будет ли доступ работать быстрее до Node.Kids, если я выбираю структуры? –

+0

@devhedgehog Вы не заботитесь о «высвобождении ссылки» для классов. Когда вы не можете добраться до объекта из любого места, он автоматически становится пригодным для сбора мусора. –

+0

@downvoter: Пожалуйста, объясните, что не так; в противном случае downvote довольно бессмыслен. –

Смежные вопросы