Я ходил в XNA и видел, что класс Vector3
в нем использует публичные поля вместо свойств. Я попробовал быстрый тест и нашел, что для struct
разница довольно драматична (добавление двух векторов вместе 100 миллионов раз заняло 2.0 с свойствами и 1.4 с полями). Для ссылочного типа разница не кажется такой большой, но она есть.Почему открытые поля быстрее, чем свойства?
Почему это так? Я знаю, что свойство скомпилировано в методы get_X
и set_X
, которые будут нести служебные расходы на вызов метода. Тем не менее, разве эти простые геттеры/сеттеры всегда встраиваются в JIT? Я знаю, что вы не можете гарантировать то, что решает JIT, но, конечно, это довольно высоко в списке вероятности? Что еще есть, что отделяет публичное поле от свойства на уровне машины?
И одна вещь, о которой я задавался вопросом: как реализована автоматическая реализация (public int Foo { get; set; }
) «лучше» OO-дизайн, чем публичное поле? Или лучше сказал: как эти два разные? Я знаю, что сделать это свойство проще с отражением, но что-нибудь еще? Уверен, что ответ на оба вопроса - одно и то же.
BTW: Я использую .NET 3.5 SP1, который, я считаю, исправил проблемы, когда методы с structs (или методы из структур, я не уверен) не были вставлены, так что это не так. Я думаю, что я использую его по крайней мере, он определенно установлен, но опять же, я использую Vista 64-бит с SP1, который должен иметь DX10.1, за исключением того, что у меня нет DX10.1.
Также: да, я бег релиз сборка :)
EDIT: Я ценю быстрые ответы, ребята, но я указал, что я делать знают, что доступ к свойству является вызовом метода, но я не» t знать, почему, по-видимому, встроенный метод медленнее, чем прямой доступ к полям.
EDIT 2: Так что я создал еще один struct
, который используется явный GetX() методы (о том, как я не скучаю по моей Java дней на все) и выполняется так же отключен ли я в-подкладки на нем (через [MethodImplAttribute(MethodImplOptions.NoInlining)]
) или нет, так что вывод: нестатические методы, по-видимому, никогда не встраиваются, даже не в структуры.
Я думал, что существуют исключения, в которых JIT может выбрать вызов виртуального метода. Почему это не может произойти в структурах, которые не знают наследования, и поэтому вызов метода может указывать только на один возможный метод, верно? Или это потому, что вы можете реализовать на нем интерфейс?
Это своего рода позор, так как это действительно заставляет меня думать об использовании свойств на производительность критического материала, но с использованием полей заставляет меня чувствовать себя грязным и я мог бы также написать, что я делаю в С.
EDIT 3: Я нашел this публикации по тому же вопросу. Его конечный вывод состоит в том, что вызов свойства действительно оптимизировался. Я также мог бы поклясться, что я много раз читал, что простые свойства getter/setter будут выровнены, несмотря на то, что они были callvirt
в IL. Так сойду с ума?
EDIT 4: Reed Copsey отправил ответ в комментарии ниже:
Re: Edit3 - см мой обновленный комментарий: Я считаю, что это x86 JIT против проблем x64 JIT. JIT в x64 не столь зрелый. Я ожидал бы, что MS улучшит это быстро, так как все больше 64-битных систем выходят в интернет каждый день. - Рид Copsey
И мой ответ на его ответ:
Спасибо, это ответ! Я пытался форсировать сборку x86, и все методы были одинаково быстрыми и намного быстрее, чем x64. Это на самом деле очень шокирует меня, я понятия не имел, что живу в каменном веке на своей 64-битной ОС. Я включу ваш комментарий в свой ответ, чтобы он стал лучше. - JulianR
Спасибо всем!
Вопрос: Что произойдет, если поле открыто, но есть свойство. Тогда она включена? – Quibblesome
Не похоже, нет. – JulianR
Re: Edit3 - см. Мой обновленный комментарий: Я считаю, что это x86 JIT vs x64 JIT. JIT в x64 не столь зрелый. Я ожидал бы, что MS улучшит это быстро, так как все больше 64-битных систем выходят в интернет каждый день. –