2009-03-20 2 views
7

MSDN говорит, что класс, который должен быть 16 байт или меньше, будет лучше обрабатываться как структура [citation].
Почему?
Означает ли это, что если структура более 16 байт, она менее эффективна, чем класс, или она то же самое?
Как вы определяете, имеет ли ваш класс менее 16 байт?
Что ограничивает структуру, действуя как класс? (кроме того, чтобы запретить создание без параметров конструкторов)Вопросы о структурах

+0

Вы можете найти много информации о структурах C# здесь: http://stackoverflow.com/questions/85553/when-should-i-use-a-struct-instead-of-a-class –

+0

У вас есть вероятно, уже нашел его, но в MSDN есть еще тонна: здесь http://msdn.microsoft.com/en-us/library/ms229017.aspx –

+0

Я только что обнаружил, что _right_, прежде чем вы разместили его. Благодаря! – Malfist

ответ

6

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

  • Структуры являются значения типа, классы ссылочного типа. Если вы используете 16 байт для общего хранилища, вероятно, не стоит создавать ссылки на память (от 4 до 8 байтов) для каждого из них.
  • Если у вас действительно маленькие объекты, их часто можно выталкивать в стек IL, а не ссылаться на объекты. Это может действительно ускорить некоторый код, поскольку вы устраняете разницу в памяти на стороне вызываемого абонента.
  • В IL есть немного лишнего «пуха», связанного с классами, и если ваша структура данных очень мала, ни один из этих пухов не будет использоваться в любом случае, так что это просто лишний барахло, который вам не нужен.

Самое важное отличие между структурой и классом состоит в том, что структуры являются типами значений, а классы являются ссылочным.

+0

О! извините - должен был написать «Промежуточный язык», который является сокращением для всего «CLR», обычного языка исполнения - это виртуальная машина, которая запускает код .NET. – Mike

+0

Хорошо, как JVM? – Malfist

+0

Я думаю, что IL ~ java bytecode и CLR ~ JVM – eglasius

0

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

Об ограничениях: вы не можете назначить его нулевому (хотя вы можете использовать Nullable <>), и вы должны его инициализировать сразу же.

+0

MSDN говорит, что Struct хранится в стеке, а класс хранится в куче. – Malfist

+1

Да, это правда. Переменные стека могут пересекаться быстрее, чем переменные кучи.Но когда вы передаете структуру как параметр методу, она будет полностью скопирована в стек до вызова метода, тогда как для класса будет скопирован только указатель. – Groo

2

Проверьте эту ссылку, я нашел ее на одном из ответов в SO сегодня: .NET Type Internals. Вы также можете попробовать выполнить поиск SO и Googling для «ссылочных типов и типов значений» для различий между структурами и классами.

Что ограничивает структуру от действия как класс?

Есть много отличий. Например, вы не можете наследовать структуру.

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

+0

«Не много benifit в добавлении методов экземпляра в структуру» - Можете ли вы расширить это дальше? Я нашел его полезным, т. Е. Добавив ToString() –

+0

. Большинство классов должны быть запечатаны, но я вижу вашу точку. – Malfist

+0

@Neil: Я немного перефразировал его, извиняюсь за плохой выбор слов. – Groo

0

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

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

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

0

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

Я бы не поощрял использование структур, тем не менее, потому что это могло вызвать некоторые тонкие ошибки: например. когда вы меняете поле структуры, оно не будет отображаться для вызывающего (потому что вы только изменили копию) - это совершенно другое поведение для классов.

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

3

«Эффективно», вероятно, они говорят о количестве памяти, которое требуется для представления класса или структуры.

На 32-битной платформе для выделения объекта требуется минимум 16 байт. На 64-битной платформе минимальный размер объекта составляет 24 байта. Итак, если вы смотрите на это исключительно из объема используемой памяти, структура, содержащая менее 16 байт данных, будет «лучше», чем соответствующий класс.

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

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

0

Копирование экземпляра структуры занимает меньше времени, чем создание нового экземпляра класса и копирование данных из старого, но экземпляры классов могут быть разделены, а экземпляры структуры не могут. Таким образом, «structvar1 = structvar2» требует копирования нового экземпляра структуры, тогда как «classvar1 = classvar2» позволяет classvar1 и classvar2 ссылаться на один и тот же экземпляр структуры (без необходимости создания нового).

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

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