Поле резервного копирования и ключевое слово значения в установщике свойств

У меня есть свойство с резервным полем и некоторой логикой внутри установщика. Интересно, следует ли мне использовать ключевое слово value или вспомогательное поле.

Вариант 1:

private bool _backingField;
public bool MyProperty
{
    get => _backingField;
    set
    {
        _backingField = value;
        if(value) // <--
        {
            ...
        }
    }
}

Вариант 2:

private bool _backingField;
public bool MyProperty
{
    get => _backingField;
    set
    {
        _backingField = value;
        if(_backingField) // <--
        {
            ...
        }
    }
}

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

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


Изменить: этот вопрос не основан на мнении, так как я спрашиваю, есть ли объективная разница.


person Sipo    schedule 14.08.2019    source источник
comment
Я бы не ожидал разницы.   -  person Llama    schedule 14.08.2019
comment
Итак, вы спрашиваете, имеет ли значение чтение той или иной переменной измеримой разницы? Нет, не думаю.   -  person Steve    schedule 14.08.2019
comment
@Steve - не все переменные одинаковы.   -  person Sipo    schedule 14.08.2019
comment
совершенно новый уровень нелепости - хорошо, что вы это понимаете ;). Мои 5 центов: в сценарии многопоточности использование value предпочтительнее, но производительность - глупый критерий.   -  person Sinatr    schedule 14.08.2019
comment
@Sinatr - Почему? Каковы будут последствия использования резервного поля в многопоточном сценарии?   -  person Sipo    schedule 14.08.2019
comment
Я не знаю, кто проголосовал за закрытие этого вопроса на основе вопросов, основанных на мнениях, но я спрашиваю, есть ли объективная разница, которую я не замечаю.   -  person Sipo    schedule 14.08.2019
comment
@Сипо, почему? Поскольку value является параметром, доступ к полям должен быть синхронизирован. Поле чтения может вернуть другое значение, чем вы только что установили.   -  person Sinatr    schedule 14.08.2019
comment
Перейти к дизассемблированию и сравнить перевод, чтобы убедиться, есть ли какая-либо разница или нет (может отличаться и в сборке релиза/отладки)?   -  person Tom    schedule 14.08.2019


Ответы (1)


Вот IL, созданный с помощью if(value) в режиме Release:

.method public hidebysig specialname instance void 
        set_MyProperty(bool 'value') cil managed
{
  // Code size       21 (0x15)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stfld      bool ConsoleApp1.Program::_backingField
  IL_0007:  ldarg.1
  IL_0008:  brfalse.s  IL_0014
  IL_000a:  ldstr      "true"
  IL_000f:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0014:  ret
} // end of method Program::set_MyProperty

Обратите внимание, что я добавил Console.WriteLine("true"); в тело if, чтобы предотвратить его удаление компилятором.

Теперь ИЛ с if (_backingField):

.method public hidebysig specialname instance void 
        set_MyProperty(bool 'value') cil managed
{
  // Code size       26 (0x1a)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldarg.1
  IL_0002:  stfld      bool ConsoleApp1.Program::_backingField
  IL_0007:  ldarg.0
  IL_0008:  ldfld      bool ConsoleApp1.Program::_backingField
  IL_000d:  brfalse.s  IL_0019
  IL_000f:  ldstr      "true"
  IL_0014:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0019:  ret
} // end of method Program::set_MyProperty

Единственным отличием является дополнительный вызов ldfld bool ConsoleApp1.Program::_backingField во второй версии, поэтому теоретически он должен быть на тик медленнее. Однако эта галочка должна быть ничтожно мала.

person Bill Tür    schedule 14.08.2019