2010-12-06 1 views
9

Я занимаюсь разработкой CIL, которая добавляет CIL ко всем методам сборки (другими словами, множеству методов). Каждый метод проверяет, является ли конкретное значение нулевым. Пример (C# Reflector'd версия CIL кода):Фактическая производительность полей по сравнению с свойствами

// CIL woven region start 
if (MyType.Something == null) { 
// ... some new stuff 
} 
// CIL woven region end 

Что такое влияние на производительность, имеющий MyType.Something как свойство против полем? Я знаю, что я прочитал, что компилятор C# выполняет специальные оптимизации, и в этом случае не должно быть никакого влияния на производительность ... но как насчет в случае прямого кода CIL (нет компилятора C#) ...? Или это JIT-компилятор, который позволяет использовать эти оптимизации (так что по-прежнему имеет преимущество CIL-код)?

Излучает OpCode.Call для аксессуаров статического свойства, имеет более низкую производительность, чем Ldsfld (помните, что это связано с десятками тысяч вызовов, поскольку каждый метод сборки сплетен)?

Спасибо.

+0

Не могли бы вы объяснить, почему вы решили реализовать это? – Andrey 2010-12-06 17:55:37

+0

Реализовать что? – Jeff 2010-12-06 18:00:25

ответ

13

При разработке математической библиотеки для SlimDX мы обнаружили, что на платформах pre-.NET 3.5 SP1 использование полей для членов математических типов (таких как X, Y, Z для Vector3) дало непропорциональную производительность увеличение по свойствам. Другими словами, разница была заметна для небольших математических функций, которые получили доступ к свойствам.

С этого момента было улучшено с .NET 3.5 SP1 (см. JIT inling). Хотя я считаю, что JIT до этого все еще будет встроен в небольшие методы (в конце концов, свойства - это просто методы), в ранних фреймах есть ошибка, которая препятствует встраиванию методов, которые принимают или возвращают типы значений.

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

4

Компилятор C# не будет оптимизировать это, нет, но JIT-компилятор обычно может задавать тривиальные (и не виртуальные) свойства, насколько мне известно.

Как и во всех вопросах производительности, хотя: при сомнительных испытаниях!

+0

Я не уверен, как тестировать, не испытывая эффекта «наблюдателя», поэтому я надеялся, что кто-то узнает это. – Jeff 2010-12-06 18:08:23

2

Эффект незначительный в любом направлении. Если ваши свойства выглядят следующим образом:

public static SomeType PropertyName 
{ 
    get {return MyType.propertyName;} 
    set {MyType.propertyName = value;} 
} 

Там действительно должно быть очень незначительное различие. Компилятор Jit должен вставлять callMyType.set_Property в полевую нагрузку, но даже если он не может из-за ошибки. Я лично ошибаюсь на стороне осторожности и придерживаюсь свойств сеттеров и геттеров, как потенциально тело метода может измениться, и, как результат, доступ к исходным данным/мутация может быть недостаточным.

Если вы хотите протестировать, вы можете заставить метод, который вы используете, использовать MethodImpl, который отключает встраивание или оптимизацию. И затем сравните разницу, я действительно сомневаюсь, что это будет значительным.