Подтвердить что ты не робот

Эксплуатационные расходы "нового" на С#?

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

4b9b3361

Ответ 1

Существует три части стоимости new:

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

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

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

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

Ответ 2

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

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

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

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

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

ИЗМЕНИТЬ

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

Ответ 3

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

Ответ 4

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

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

ИЗМЕНИТЬ

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

Подробнее об этом см. ниже.

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

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

Вы должны искать С++ для этой цели, так как там есть деструкторы.

~ClassName()
{
//kill my object and reclaim memory.
}

Ответ 9

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

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