Почему открытые поля быстрее, чем свойства?

Я Vector3 в XNA и видел, что class Vector3 в нем использует публичные поля вместо свойств. Я попробовал быстрый тест и обнаружил, что для struct разница довольно драматична (добавление двух векторов вместе 100 миллионов раз заняло 2.0 с свойствами и 1.4 с полями). Для ссылочного типа разница не кажется такой большой, но она есть.

Так почему это? Я знаю, что свойство скомпилировано в get_X и set_X , что может set_X к накладным расходам метода. Однако, разве эти простые геттеры / сеттеры всегда не встраиваются в JIT? Я знаю, что вы не можете гарантировать то, что решает JIT, но, конечно, это довольно высоко в списке вероятности? Что еще есть, что отделяет публичное поле от свойства на уровне машины?

И одна вещь, о которой я задавался вопросом: как это свойство автоматически реализовано ( public int Foo { get; set; } ), лучше «OO-дизайн», чем публичное поле? Или лучше сказал: как эти два разных ? Я знаю, что сделать это свойство проще с reflectionм, но что-нибудь еще? Уверен, что ответ на оба вопроса – одно и то же.

BTW: Я использую .NET 3.5 SP1, который, как я считаю, фиксировал проблемы, когда методы с structs (или методы структур, я не уверен) не были связаны друг с другом, так что это не так. Я думаю, что я использую его по крайней мере, он определенно установлен, но опять же, я использую Vista 64-бит с SP1, который должен иметь DX10.1, за исключением того, что у меня нет DX10.1 ..

Также: да, я запускал сборку релизов 🙂

EDIT : Я ценю ответы на быстрые ответы, но я указал, что знаю, что доступ к свойствам является вызовом метода, но я не знаю, почему, по-видимому, встроенный метод медленнее, чем прямой доступ к полям.

EDIT 2 : Итак, я создал другую struct которой использовались явные методы GetX (), как я вообще не пропустил свои Java-дни), и это было выполнено, независимо от того, отключен ли я на ней (через [MethodImplAttribute(MethodImplOptions.NoInlining)] ) или нет, поэтому вывод: нестатические методы, по-видимому, никогда не встраиваются, даже не в структуры.

Я думал, что есть исключения, где JIT может optmize вызов виртуального метода. Почему это не может произойти в структурах, которые не знают наследования, и поэтому вызов метода может указывать только на один возможный метод, верно? Или это потому, что вы можете реализовать на нем интерфейс?

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

EDIT 3 : Я нашел эту запись о том же предмете. Его конечный вывод состоит в том, что вызов свойства действительно оптимизировался. Я также мог бы поклясться, что много раз читал, что простые свойства getter / setter будут выровнены, несмотря на то, что они являются callvirt в IL. Так сойду с ума?

EDIT 4 : Рид Копси опубликовал ответ в комментарии ниже:

Re: Edit3 – см. Мой обновленный комментарий: Я считаю, что это x86 JIT vs x64 JIT. JIT в x64 не столь зрелый. Я ожидал бы, что MS улучшит это быстро, так как все больше 64-битных систем выходят в интернет каждый день. – Рид Копси

И мой ответ на его ответ:

Спасибо, это ответ! Я пытался форсировать сборку x86, и все методы были одинаково быстрыми и намного быстрее, чем x64. Это на самом деле очень шокирует меня, я понятия не имел, что живу в каменном веке на своей 64-битной ОС. Я включу ваш комментарий в свой ответ, чтобы он стал лучше. – JulianR

Всем спасибо!

Изменить 2:

У меня была другая мысль:

Вы упомянули, что вы работаете на x64. Я тестировал эту же проблему на x86 и видел такую ​​же производительность при использовании auto-properties vs. fields. Однако, если вы посмотрите вокруг сообщений Connect и рассылки / сообщений на форуме, есть много ссылок в Интернете на то, что JIT для CLR x64 является другой базой кода и имеет очень разные характеристики производительности для x86 JIT. Я предполагаю, что это одно место, где x64 все еще отстает.

Кроме того, FYI, объект struct / method / etc, установленный в .net 3.5sp1, был на стороне x86, и был тот факт, что вызовы методов, которые занимали структуры как параметр, никогда не были бы встроены в x86 до .net3.5sp1. Это почти не имеет отношения к этой дискуссии в вашей системе.


Редактировать 3:

Другое дело: о том, почему XNA использует поля. Я на самом деле был на Game Fest, где они объявили XNA. Рико Мариани рассказал, где он поднял многие те же моменты, что и в своем блоге. Кажется, у XNA были похожие идеи, когда они разработали некоторые из основных объектов. Видеть:

http://blogs.msdn.com/ricom/archive/2006/09/07/745085.aspx

В частности, проверьте пункт №2.


Что касается того, почему автоматические свойства лучше, чем открытые поля:

Они позволяют вам изменять реализацию в v2 вашего classа и добавлять логику в процедуру get / set свойства по мере необходимости, не меняя свой интерфейс на конечных пользователей. Это может оказать глубокое влияние на вашу способность поддерживать вашу библиотеку и код с течением времени.

—- От оригинального сообщения – но обнаружил, что это не проблема ——–

Вы запустили сборку релиза вне VS? Это может быть одним из объяснений того, почему вещи не оптимизируются. Часто, если вы работаете в VS, даже оптимизированная версия сборки, хост-процесс VS отключает многие функции JIT. Это может привести к изменению показателей производительности.

Вы должны прочитать эту статью Vance. В нем подробно описывается, почему методы не всегда встроены JIT’er, даже если они выглядят совершенно очевидно, что они должны быть.

http://blogs.msdn.com/vancem/archive/2008/08/19/to-inline-or-not-to-inline-that-is-the-question.aspx

  • Открытые поля – это прямые задания
  • Свойства – это методы, затем больше кода, несущественные, но более.

XNA должен ориентироваться на XBox 360, а JIT в .NET Compact Framework не такой сложный, как его настольный аналог. .NET CF JIT’er не будет встроить методы свойств.

Доступ к полю – это просто ссылка на память, в то время как использование свойства фактически вызывает метод и включает служебные данные вызова функции. Причина использования свойств, а не полей, заключается в том, чтобы изолировать ваш код от изменений и обеспечить лучшую степень детализации доступа. Не подвергая ваше поле напрямую, вы больше контролируете, как осуществляется доступ. Использование автоматических полей позволяет получить типичное поведение getter / setter, но создает возможность изменять это без последующей необходимости внесения изменений в другие части кода.

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

  • Определения @property с ARC: сильные или сохраняются?
  • Почему нам нужны свойства в C #
  • Причина использования ivars против свойств в объекте c
  • Как читать файл свойств в веб-приложении?
  • Обратный вызов, когда свойство зависимостей получает изменение xaml
  • `def` vs` val` vs `lazy val` в Scala
  • Свойство '' не найдено на объекте типа 'id'
  • Свойства vs Методы
  • Json.NET (Newtonsoft.Json) - Два «свойства» с таким же именем?
  • Как получить значение свойства bean, когда само имя свойства является динамической переменной
  • Как проверить, имеет ли объект определенный метод / свойство?
  • Давайте будем гением компьютера.