2010-07-23 2 views
2

В C# (или VB .NET) компилятор пытается оптимизировать доступ к свойствам? Для например.,C# Оптимизация доступа к объектам

 

public ViewClass View 
{ 
    get 
    { 
     ... 
     Something is computed here 
     .... 
    } 
} 

if (View != null) 
    View.Something = SomethingElse; 

 

Я бы предположил, что если компилятор может каким-то образом определить, что View остается постоянным между двумя обращениями, он может отказаться от вычисления значения в два раза. Выполнены ли эти оптимизации?

Я понимаю, что если View имеет некоторые интенсивные вычисления, вероятно, он должен быть реорганизован в функцию (GetView()). В моем конкретном случае View предполагает восхождение на визуальное дерево, ищущее элемент определенного типа.

Связанные: Любые ссылки на работу компилятора (Microsoft) C#?

+0

Как компилятор знал бы, что значение не изменилось? Что делать, если класс используется в многопоточном коде? – tster

+0

@tster: Предположительно, у компилятора есть хрустальный шар. –

ответ

5

Не в общем, нет. Как отметил Стивен, есть множество факторов, которые следует учитывать в отношении многопоточности, если вы действительно используете что-то, что может измениться, вы правы, его нужно переучивать вне собственности. Если это не изменится, вы должны lazy-load it (проверьте, является ли частный член нулевым, если он затем вычисляет, а затем возвращает значение).

Если он не изменится и зависит от параметра, вы можете использовать Dictionary или Hashtable в качестве кеша - данный параметр (ключ) вы сохраните это значение. Вы можете иметь каждую запись как WeakReference для значения, поэтому, когда значение не упоминается нигде, и происходит сбор мусора, память будет освобождена.

Надеюсь, что это поможет.

+0

Спасибо, что подняли некоторые другие факторы. –

1

Нет, поэтому вы должны использовать Lazy<T> для реализации расчета JIT.

0

В моем понимании нет неявного кэширования - вы должны кэшировать значение данного свойства себя первый раз, когда он рассчитывается

Например:

object mCachedValue = null; 
    public Object MyProperty 
    { 
     get 
     { 

      if (mCachedValue == null) 
      { 
       lock(mCachedValue) 
       { 
        //after acquiring the lock check if the property has not been initialized in the mean time - only calculate once 
        if (mCachedValue == null) 
        { 
         //calculate value the first time 
        } 
       } 
      } 
      return mCachedValue; 
     } 
+0

Идея правильная, но этого кода нет.В нем нет безопасности потоков, поэтому я рекомендовал вместо этого использовать «Lazy ». –

+0

Вы правы, я не рассматривал многопоточность. Я изменил код, чтобы принять во внимание безопасность потока. – Ando

+1

Ненависть к разочарованию, но это тоже не обязательно сработает. Просто используйте 'Lazy '. Не верьте мне на слово: http://csharpindepth.com/Articles/General/Singleton.aspx –

2

Вопрос очень неясен, для меня не очевидно, как связаны геттер и фрагмент под ним. Но да, аксессоры свойств обычно сильно оптимизированы. Не компилятором C#, компилятором JIT. Во-первых, они часто встроены, поэтому вы не платите за стоимость вызова метода.

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

get 
{ 
    if (_something == null) { 
     _something = createSomething(); 
    } 
    return _something; 
} 

Это будет встраивать общий случай и дать метод создания оставаться не-встраиваемыми. Обычно это скомпилировано в три команды машинного кода в сборке Release (load + test + jump), примерно на nano-second времени выполнения. Это микро-оптимизация, поскольку фактическое совершенство перфорации было бы довольно редко.

Обратите внимание, что данный пример кода не является потокобезопасным. Всегда сначала пишите правильный код, а не быстрый код.

+0

Ханс, можете ли вы подтвердить, должен ли вызывающий абонент быть в той же сборке, чтобы свойство было встроено? –

+1

@Steven, я могу подтвердить это * не * должен быть в той же сборке. Это разрушило бы разработку свойств платформы .NET. –

+0

Полезно знать. Вы могли бы разместить ссылку ссылки? –

Смежные вопросы