2010-07-23 3 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

합니다. 스티븐 (Steven)은 멀티 스레딩과 관련하여 고려해야 할 많은 요소가 있음을 언급했듯이 진정으로 변화 할 수있는 것을 컴퓨팅하는 경우 속성에서 리팩토링해야한다는 것이 맞습니다. 변경되지 않으면 lazy-load해야합니다 (private 멤버가 null인지 확인한 다음 계산 한 다음 값을 반환합니다).

변경되지 않고 매개 변수에 따라 다르면 값을 저장할 매개 변수 (키)가있는 경우 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

질문은 매우 불분명합니다. 그 아래 getter와 스 니펫이 어떻게 관련되어 있는지는 분명하지 않습니다. 하지만 그렇습니다. 속성 접근자는 일반적으로 많이 최적화됩니다. JIT 컴파일러에 의한 C# 컴파일러가 아닙니다. 하나는 메소드 호출 비용을 지불하지 않으므로 종종 인라인됩니다.

getter에 너무 많은 코드가 포함되어 있지 않고 원숭이가 잠금 및 예외 처리를하지 않는 경우에만 발생합니다. 이 같은 코드를 가진 일반적인 경우를 최적화하기 위해 JIT 컴파일러를 도움이 될 수 있습니다

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

이것은 일반적인 경우 인라인 및 작성 방법은 않은 인라인을 유지 할 수 있습니다. 이것은 일반적으로 릴리스 빌드 (load + test + jump)에서 실행 시간의 나노 초에 해당하는 세 가지 기계 코드 명령어로 컴파일됩니다. 이것은 실제 성능 향상이 매우 드뭅니다. 마이크로 최적화입니다.

주어진 샘플 코드는 스레드로부터 안전하지 않습니다. 빠른 코드보다는 항상 올바른 코드를 작성하십시오.

+0

Hans, 호출자가 속성을 인라인하기 위해 동일한 어셈블리에 있어야하는지 확인할 수 있습니까? –

+1

@Steven, 나는 그것이 같은 어셈블리에 있어야하지 않는지 * 확인할 수 있습니다. .NET 프레임 워크 속성을 인라 이닝하는 것은 망설이게됩니다. –

+0

잘 알고 있습니다. 참조 링크를 게시 할 수 있습니까? –