Производительность стоимость «нового» в C #? - PullRequest
30 голосов
/ 23 ноября 2010

В C # какова цена эффективности использования нового ключевого слова?Я конкретно спрашиваю, что касается разработки игр, я знаю, что в C ++ определенно нет-нет обновлять вещи каждый цикл обновления.Относится ли то же самое к C #?Я использую XNA и разрабатываю для мобильных устройств.Просто спрашиваю как вопрос оптимизации.

Ответы [ 9 ]

35 голосов
/ 23 ноября 2010

Есть три части стоимости new:

  • Выделение памяти (может не потребоваться, если это тип значения)
  • Запуск конструктора (в зависимости отчто вы делаете)
  • Стоимость сборки мусора (опять же, это может не применяться, если это тип значения, в зависимости от контекста)

Трудно использовать C # идиоматически, даже не создавая любые новые объекты в вашем основном коде ... хотя я осмелюсь сказать, что это возможно, если использовать объекты как можно интенсивнее.Попытайтесь заполучить некоторые реальные устройства и посмотрите, как работает ваша игра.

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

Распределитель и сборщик мусора довольно хороши в .NET, хотя, вероятно, будут прощена устройстве (Windows Phone 7, я полагаю)?В частности, я не уверен, имеет ли Compact Framework CLR (который используется в WP7) GC поколения.

19 голосов
/ 23 ноября 2010

Распределение в C # на самом деле быстрее, чем в C ++. Это просто включает увеличение указателя кучи и возврат этого указателя. Как правило, объекты в C # поднимаются newed чаще, чем в C ++, поскольку в таких вещах, как strings .

, немного больше неизменности.

Как уже отмечали другие, настоящий зверь - это сборщик мусора, который немного сложно описать. Тем не менее, даже GCing в большинстве случаев так же быстр, если не быстрее, чем delete в C ++ - просто вы не можете предсказать, когда это произойдет.

Несколько советов Рико Мариани, парня из команды .NET: http://msdn.microsoft.com/en-us/library/ms973837.aspx

Это немного устарело, и в GC было несколько улучшений, но большая часть информации все еще актуальна.

Я должен добавить, что сборщик мусора XNA / Compact Framework несколько медленнее, чем в версии x86, компенсирует ЦП на производительность памяти, поэтому вам следует остерегаться этого.

EDIT

Я забыл упомянуть, и это важно: типы значений , включая структуры, также используют синтаксис new, но они создаются в стеке, а не в куче, поэтому нет Стоимость GC для тех, кого вы коробка их.

6 голосов
/ 23 ноября 2010

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

5 голосов
/ 23 ноября 2010

Вы всегда должны кодировать «самый простой» способ , затем измерять узкие места, , если они присутствуют.

В любом случае, я бы никогда не кодировал игры на C #.

РЕДАКТИРОВАТЬ

Поскольку это вызвало недовольство, я имею в виду, что никогда не буду кодировать в C # , если бы C ++ был доступной опцией.Это то, что я подумал, так как ОП также помечен C ++.

3 голосов
/ 23 ноября 2010

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

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

2 голосов
/ 23 ноября 2010

С новым оператором в c # практически нет затрат, но когда вы используете new для ссылочного типа, будет выделяться куча, и это будет поддерживаться GC.Если память ограничена, то выделение памяти является просто движением указателя, но если GAP между двумя выделениями найден, то GC сверится со свободным списком доступной памяти (список ссылок), чтобы найти требуемый объект, это потребует некоторого времени o (nПутешествие во времени.

См. Сообщение Эрика Липперта

1 голос
/ 04 сентября 2013

Когда вы пишете new в c #, CLR выделяет память для объекта в управляемой куче.

Пожалуйста, посмотрите на ссылку ниже для получения дополнительной информации по этому вопросу:

http://msdn.microsoft.com/en-us/library/ee787088(v=vs.100).aspx

Поскольку сборка мусора в C # автоматическая (только в том случае, когда во время тестирования люди используют GC.Collect , чтобы запустить ее вручную), игровой дизайн на c # - плохая идея.

Вам следуетищите C ++ для этой цели, поскольку у вас есть деструкторы.

~ClassName()
{
//kill my object and reclaim memory.
}
1 голос
/ 23 ноября 2010

В C # память хранится дефрагментированной сборщиком мусора, поэтому поиск и выделение памяти - это очень быстрые операции.Однако время от времени дефрагментация, выполняемая GC, может значительно замедлиться

0 голосов
/ 13 октября 2015

Мое измерение показывает, что «новый» для эталонного типа может иногда занимать до 2,2 секунд, а иногда и с несколькими тиками. Суть в том, что в .net GC нет гарантии в реальном времени, и производительность может значительно варьироваться случайным образом. Так что я бы посоветовал для проектов в реальном времени, например, в играх, не называйте «новые» ссылочные типы в части кода в реальном времени (например, в циклах обновления), потому что нет гарантии в реальном времени.

Конечно, многие люди будут утверждать, что как часто «новый» будет занимать 2,2 секунды, и имеет ли это значение, если это происходит только раз в несколько часов. Ну, это должно быть решение дизайнера. Но ради академических аргументов, GC не в реальном времени, поэтому не называйте «новым» в кодах реального времени.

...