Если я делаю эти классы векторов или структуры в C#

Я создаю библиотеку геометрии в C#, и мне будут нужны следующие неизменные типы:

  • Vector2f (2 floats - 8 байтов)
  • Vector2d (2 doubles - 16 байтов)
  • Vector3f (3 floats - 12 байтов)
  • Vector3d (3 doubles - 24 байта)
  • Vector4f (4 floats - 16 байтов)
  • Vector4d (4 doubles - 32 байта)

Я пытаюсь определить, сделать ли их структурами или классами. MSDN предлагает только использовать структуру если размер при попытке быть не больше, чем 16 байтов. Та ссылка, кажется, с 2005. 16 байтов являются все еще макс. предложенным размером?

Я уверен что с помощью структур для float векторы были бы более эффективными, чем использование класса, но что я должен сделать о double векторы? Я должен сделать их структурами также, чтобы быть последовательным, или я должен сделать их классами?

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

8
задан dewald 19 April 2010 в 18:38
поделиться

8 ответов

Microsoft XNA Framework использует структуры для своих типов данных Vector2 / 3 / 4 . Они содержат поля типа float . Я не вижу ничего плохого в том, чтобы делать то же самое; использование полей типа double не должно иметь большого значения.

8
ответ дан 5 December 2019 в 07:34
поделиться

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

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

2
ответ дан 5 December 2019 в 07:34
поделиться

Структуры, определенно. Почему? Ну, это отчасти ощущение, я думаю, вектор просто ощущается и ведет себя как значение .

Рико Мариани здесь приводит некоторые причины, по которым типы значений были выбраны для определенных типов для API (я не думаю, что он говорит о XNA).

И хотя здесь решающим фактором является эффективность, я думаю, что дело не в сборке мусора, а в плотности данных , как говорит Рико. Скажем, у вас также есть тип Vertex , который содержит два Vector3 s: Vector3 для нормального и Vector3 для мирового co. -координаты.Если вы создали классы этих типов, то наличие массива из 100 Vertex элементов будет состоять из:

  • 100 * 8 байтов (8 байтов, я считаю, накладные расходы класса в памяти, 4 байта для заголовок типа и 4 байта для чего-то еще, дескриптора GC?)
  • 100 * 4 байта (для указателей в массиве на элементы Vertex )
  • 200 * 4 байта (для указатели от каждой вершины на два элемента Vector3 )
  • 200 * 8 байтов (для 8-байтовых накладных расходов, которые вы платите за создание класса Vector3 )
  • 200 * 12 байт (для фактической полезной нагрузки 3 float на Vector3 )

6000 байт (в 32-битной системе).

Как тип значения, это просто 200 * 12 байт = 2400 байт. Гораздо более эффективный с точки зрения пространства, не говоря уже о более низком уровне косвенности при чтении массива.

Но занимание много места не обязательно замедляет его, неправильное использование типа значения может быть медленнее, чем создание класса, как я обнаружил . Вы определенно хотите передать их с помощью ref в максимально возможной степени, избегайте их копирования, но это не относится к всем операциям, поэтому измерьте. Думаю, я помню, что вычисление скалярного произведения происходило медленнее при прохождении ref , возможно, потому, что это каким-то образом предотвращало встраивание, увеличивая IL. Но не верьте мне на слово, просто измерьте.

3
ответ дан 5 December 2019 в 07:34
поделиться

Неизменяемые структуры - хороший выбор. Рекомендуемый размер в MSDN самый слабый, 32 байта - это не очень много.

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

Хорошей параллелью являются новые структуры Complex и BigInteger в dotNet 4

4
ответ дан 5 December 2019 в 07:34
поделиться

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

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

2
ответ дан 5 December 2019 в 07:34
поделиться

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

4
ответ дан 5 December 2019 в 07:34
поделиться

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

http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx?ArticleID=9adb0e3c-b3f6-40b5-98b5-413b6d348b91

-1
ответ дан 5 December 2019 в 07:34
поделиться

Я полагаю, вы беспокоитесь о производительности?

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

Если вы вообще нацелены на .NET CE, вам, вероятно, стоит подумать об использовании структур, поскольку GC не так эффективен, как полная реализация .NET.

0
ответ дан 5 December 2019 в 07:34
поделиться
Другие вопросы по тегам:

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