Что происходит при создании типов значений?

Я разрабатываю игру, используя XNA и С#, и пытался избежать вызова типа new struct() кода каждого кадра, поскольку я думал, что это выдохнет GC. "Но подождите, - сказал я себе, - структура - это тип значения. GC не следует так звонить, верно?" Ну, вот почему я спрашиваю здесь.

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

Возьмем, например, этот код:

spriteBatch.Draw(tex, new Rectangle(x, y, width, height), Color.White);

Прямоугольник в этом случае является структурой. Что происходит, когда создается новый Rectangle? Каковы последствия повторения этой строки много раз (скажем, тысячи раз)? Создан ли этот прямоугольник, копия, отправленная методу Draw, и затем отбрасывается (что означает, что память не будет съедена, чем больше Draw вызывается таким образом в той же функции)?

P.S. Я знаю, что это может быть предварительная оптимизация, но я в основном любопытен и хочу лучше понять, что происходит.

Ответы

Ответ 1

Когда создается новая структура, содержимое помещается прямо в то место, где вы указываете - если это переменная метода, она идет в стек; если он присваивается переменной класса, он попадает в экземпляр класса, на который указывает (в куче).

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

Несмотря на то, что может быть копирование байтов, компилятор JIT, скорее всего, оптимизирует все ненужные копии, чтобы он выполнялся как можно быстрее. Как правило, это не то, о чем вам нужно беспокоиться - это очень микро-оптимизация:)

Отвечает ли это на ваш вопрос?

Ответ 2

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

Ответ 3

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

В статье MSDN struct (C#) есть дополнительная информация об этом.

Ответ 4

Это просто добавить к ответу thecoops. Для ссылочных типов оператор new выделяет новый экземпляр типа в куче и вызывает указанный конструктор.

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

Подробнее см. описание на MSDN.