Структуры “быстрее”, чем Классы - В целом или в платформе.NET?

Так как структуры являются типами значения, их данные копируются при передаче в метод как аргумент. Пример:

int someInt = 7;

DoSomeMethod(someInt); // <-- This is passing the "value" 7.

До сих пор, легкий понять, и Вы, вероятно, задаетесь вопросом, как мой вопрос допустим..., так рассмотрите следующее:

public struct TimmysStructOfGoodness
{
    public int SomeInt1;
    public int SomeInt2;
    public int SomeInt3;
    // ... later that day ...
    public int SomeInt999;
}

и затем, со ссылкой на следующий код:

TimmysStructOfGoodness someStructOfGoodness = new blah blah blah...

DoSomeMethod(someStructOfGoodness); // <-- **HERE IS WHERE THE QUESTION APPLIES!**

Вышеупомянутая попытка оператора выделить несколько megs поршня, чтобы "скопировать" мой тип значения (структура)?

Если ответ - да - тогда, когда/где строка между "быстрее" и "медленнее"?

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

ГЛАВНАЯ ПРАВОВАЯ ОГОВОРКА: Я знаю, что это не имеет никакого отношения, почему Вы использовали бы структуру стихи класс, и я знаю, что никогда не буду делать структуру с 999 полями - это - просто вопрос базовых внутренностей и кишок и т.п.:)

17
задан Timothy Khouri 28 December 2009 в 16:38
поделиться

5 ответов

(обновлено, благодаря вкладам других пользователей)

В отличие от класса, структура создается на стеке. Таким образом, быстрее инстанцировать (и уничтожить) структуру, чем класс.

Если только (как указал Адам Робинсон) структура не является членом класса, в этом случае она выделяется в куче вместе со всем остальным.

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

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

Если только вам не нужен тип ссылки. семантика, класс, который меньше чем 16 байт может быть эффективнее обрабатываемая системой как структура.

Это - если вам нужно передать ее по ссылке, то сделайте ее классом, независимо от размера.

Во вторых, вы все равно можете передать структуру по ссылке, просто указав ref в списке параметров функции.

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

.
14
ответ дан 30 November 2019 в 12:13
поделиться

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

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

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

Вы, конечно, можете передать структуру, используя ref/out - в этом случае копирование не произойдет - в метод будет передана ссылка на структуру. Это может быть, а может и не быть желательным - так как это позволит вызываемому методу изменять содержимое структуры.

Структура, объявленная в качестве члена класса, будет фактически выделена на куче (в составе компоновки памяти класса). Если вы передадите этот класс, то структура не будет скопирована, но все равно будет доступна через ссылку на класс.

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

object x = new MyStruct( ... );  // boxed on the heap

Jon Skeet написал хорошую статью о том, где все заканчивается в памяти, которую вам следует прочитать.

.
6
ответ дан 30 November 2019 в 12:13
поделиться

Ответ на ваш вопрос: Да. Когда Вы определяете структуру, каждое задание вызывает операцию копирования.

Нет точной линии, которая бы отделяла "быстро" от "медленно", потому что есть много факторов, которые влияют на скорость WRT для структур, таких как:

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

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

.
2
ответ дан 30 November 2019 в 12:13
поделиться

Структуры и классы не только имеют разную производительность, но и ведут себя по-разному. Вы должны использовать тот, который наиболее подходит для того типа, который вы реализуете. Рекомендации по поводу того, когда использовать тот или иной тип, четко описаны в MSDN. Используйте структуру только в том случае, если применяются все следующие правила:

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

Если вы передаете структуру в функцию, то вы получите ее копию. Если ваша структура большая, то в результате будет скопировано большое количество данных. Обычно ссылка реализована в виде 4 байт (на x86), поэтому передача объекта требует только копирования этих 4 байт.

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

.
8
ответ дан 30 November 2019 в 12:13
поделиться

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

3
ответ дан 30 November 2019 в 12:13
поделиться
Другие вопросы по тегам:

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