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