Если массив используется в качестве элемента в структуре (C #), где он хранится? - PullRequest
5 голосов
/ 20 февраля 2012

Мы используем struct в C # всегда, когда это возможно, главным образом потому, что она хранится в стеке, и для нее не создаются объекты. Это повышает производительность.

С другой стороны, массивы хранятся в куче.

У меня вопрос, если я включу массив в качестве элемента структуры, что-то вроде следующего:

struct MotionVector
{
    int[] a;
    int b;
}

Тогда каковы будут последствия. Будет ли этот массив храниться в стеке? Или преимущество в производительности при использовании struct будет потеряно?

Ответы [ 4 ]

8 голосов
/ 20 февраля 2012

В стеке будет храниться только указатель на массив.Фактический массив будет храниться в куче.

1 голос
/ 20 февраля 2012

Вы будете содержать ссылку на в своей структуре;это будет частью структуры в стеке.

Фактический объект int [], если / когда вы его инициализируете, будет идти куда угодно, в противном случае (куча в большинстве архитектур).

1 голос
/ 20 февраля 2012

int[] a - это ссылочный тип, т.е. он ссылается на массив целых чисел.Сама ссылка будет храниться в стеке.Однако данные, на которые он ссылается, будут храниться в куче, когда вы сделаете что-то вроде этого:

MotionVector z;
z.a = new int[10];
0 голосов
/ 20 февраля 2012

Если вы не хотите создавать элементы динамически, попробуйте создать (большой) буфер экземпляров MotionVector во время запуска и использовать их при необходимости. Тогда вы не получите штраф за создание / разрушение их динамически.

Конечно, вам нужно написать несколько небольших функций, чтобы получить «бесплатный» экземпляр и получить его, используйте для этого логическое значение в структуре (или с помощью интерфейса).

Чтобы сделать это, вы можете, например ::

Создайте во время инициализации вашего приложения векторы движения:

MotionVectors motionVectors;

Добавьте логическое значение в класс MotionVector:

public class MotionVector
{
    bool InUse { get; set; }

    public MotionVector() 
    {
        InUse = false; 
    }
}

Определите новый класс MotionVectors:

class MotionVectors
{
    MotionVector _instances[100];

    public void Free(MotionVector vector)
    {
        var index = 'search vector in _instances' 
        _instances[index].Inuse = false;
    }

    public MotionVector GetNewInstance()
    {
        var index = 'first free vector in _instances'
        _instances[index].Inuse = true;
        return _instances[index];
    }
}
...