Структура и класс для долгоживущих объектов

StackOverflow https://stackoverflow.com/questions/608392

  •  03-07-2019
  •  | 
  •  

Вопрос

Когда вам нужно иметь очень маленькие объекты, скажем, содержащие 2 свойства float, и у вас будут миллионы из них, которые не будут «уничтожены» сразу, лучше ли выбрать структуры или классы?

Как и в библиотеке xna, в качестве структур существуют точки point3 и т. д., но если вам нужно сохранять эти значения в течение длительного времени, будет ли это представлять угрозу производительности?

Это было полезно?

Решение

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

Несколько советов:

::Структура не должна быть больше 16 байт, иначе вы потеряете преимущества в производительности.

::Сделайте структуру неизменяемой.Это делает использование более понятным.

Пример:

public struct Point3D {

   public float X { get; private set; }
   public float Y { get; private set; }
   public float Z { get; private set; }

   public Point3D(float x, float y, float z) {
      X = x;
      Y = y;
      Z = z;
   }

   public Point3D Invert() {
      return new Point3D(-X, -Y, -Z);
   }

}

Другие советы

Ответ зависит от того, где в конечном итоге будут храниться объекты/значения.Если они должны храниться в нетипизированной коллекции, такой как ArrayList, вам придется упаковать их.Box создает оболочку объекта для структуры, и его размер такой же, как и у объекта класса.С другой стороны, если вы используете типизированный массив, такой как T[] или List, то использование структур будет хранить только фактические данные для каждого элемента с отпечатком только для всей коллекции, а не для ее элементов.

Таким образом, структуры более эффективны для использования в массивах T[].

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

Однако на практике я не думаю, что это так уж важно.Если у вас их так много, они, скорее всего, где-то являются частью экземпляра класса (в куче).

Структура кажется подходящей для этого приложения.

Имейте в виду, что «необходимость хранить эти значения» подразумевает их хранение где-то в куче, возможно, в поле массива экземпляра класса.

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

Использование класса для миллионов этих типов данных, вероятно, будет дорогостоящим из-за большого объема разыменования, которое, вероятно, будет иметь место для операций с этим типом.

Как правило, большие массивы без псевдонимов (т.unshared) данные одного типа лучше всего хранить в структурах для повышения производительности, поскольку вы уменьшаете количество косвенных обращений.(Смотрите также когда-строит-ответ).Точная разница в производительности между классом и структурой зависит от вашего использования.(Например, в операциях вы получаете доступ только к частям структуры?Вы делаете много временного копирования?Если структура небольшая, ее, вероятно, всегда лучше использовать, но если она большая, создание временных копий может замедлить работу.Если вы сделаете его неизменяемым, вам придется всегда копировать его целиком, чтобы изменить значение.)

Если сомневаетесь, измерьте.

Поскольку вас интересуют возможные долгосрочные эффекты, которые могут быть неочевидны при таком измерении, имейте в виду, что такие массивы, скорее всего, хранятся в куче больших объектов и их следует использовать повторно, а не уничтожать и перераспределять.(видеть CRL наизнанку:Обнаружена большая куча объектов.)

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

Типы значений (структуры) хороши для типов, которые не часто выделяются в куче, то есть в основном содержатся в другом ссылочном или значащем типе.

Пример Vector3, который вы привели, является прекрасным примером.Векторы Vector3 редко будут находиться в куче, большую часть времени они будут содержаться в типе, который сам находится в куче, или использоваться как локальная переменная, и в этом случае они будут размещены в стеке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top