Фактическая производительность полей и свойств - PullRequest
9 голосов
/ 06 декабря 2010

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

// 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 (имейте в виду, что это десятки тысяч вызовов, поскольку каждый метод в сборке сплетен)?

Спасибо.

Ответы [ 3 ]

13 голосов
/ 06 декабря 2010

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

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

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

5 голосов
/ 06 декабря 2010

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

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

2 голосов
/ 06 декабря 2010

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

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

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

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

...