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