2011-02-23 3 views
1

이 작은 스 니펫은 참조 된 객체를 키로 사용하여 사전에 저장된 카운트 값 (정수)을 증가시키는 것입니다. 사전이 작 으면 여러 조회가 중요하지 않지만이 사전은 상당히 커질 수 있습니다.Dictionary 값의 값 유형에 대한 포인터 사용

Private RefCount As IDictionary(Of ILifeTimeManaged, Integer) 
......... CODE HERE..... 

Private Sub IncrementRefCount(ByVal entity As ILifeTimeManaged) 

    Dim prevCount As Integer 

    ''# if we have no reference entry, add one and set its count to 1 

    If Not RefCount.TryGetValue(entity, prevCount) Then 
     RefCount.Add(entity, 1) 
    Else 
     ''# otherwise increment its count by 1 

     RefCount.Item(entity) = prevCount + 1 
    End If 

End Sub 

해당 사전 항목을 찾은 다음 값에 저장된 int를 증가 시키거나 새 사전 항목을 추가합니다.

사전 값에 대한 포인터를 사용하는 것은 좋지 않은 생각입니까? 그런 다음 이미 값을 얻었 으면 두 번째 키 조회를 피할 수 있습니다. 어떻게 구현하겠습니까? .NET4에서도 가능합니까?

IntPtr을 사용하여 어떻게 할 수 있습니까? 나쁜 생각처럼 보이지 않는 http://msdn.microsoft.com/en-us/library/system.intptr.aspx

RefCount.Item(entity) = prevCount + 1 

답변

1

C++에서와 같이 VB에서 특정 유형의 포인터를 만들 수 없습니다. 그러나 참조 유형에 값 유형을 랩핑하여 원하는 의미를 얻을 수 있습니다.

Public Class Ref(Of T As Structure) 

    Public Sub New() 
    End Sub 
    Public Sub New(ByVal value As T) 
     Me.Value = value 
    End Sub 

    Public Property Value As T 

End Class 

이렇게하면 "포인터"를 정수 (더 정확하게는 정수가 들어있는 항목에 대한 참조)로 되돌릴 수 있습니다.

Private RefCount As IDictionary(Of ILifeTimeManaged, Ref(Of Integer)) 
......... CODE HERE..... 

Private Sub IncrementRefCount(ByVal entity As ILifeTimeManaged) 
    Dim count As Integer 

    ''# if we have no reference entry, add one and set its count to 1 
    If Not RefCount.TryGetValue(entity, count) Then 
     RefCount.Add(entity, New Ref(Of Integer)(1)) 
    Else 
     ''# otherwise increment its count by 1 
     count.Value += 1 
    End If 
End Sub 

당신은 아마도 (추가 호출 같은) 구문을 단순화하기 위해 Ref 클래스에 TRef(Of T) 사이에 약간의 변환 방법을 추가 할 수 있습니다 : 당신은 다음처럼 작성할 수 있습니다. 제 의견으로는 그렇게하면 C++ 포인터보다 C++ 참조에 더 가까운 것을 얻을 수 있습니다. 그게 당신이 원하는지 아닌지는 당신에게 달린 것입니다.

수정 RE 편집 : IntPtr은 interop 코드 호출에서 모든 포인터 유형을 나타내도록 설계되었습니다. 아마도 더 좋은 이름은 NativePtr이었을 것입니다. IntPtr을 C++의 포인터처럼 원하는 방식으로 관리되는 코드로 사용할 방법이 없습니다.

+0

맞긴하지만 여기에서는 언 박싱 비용 대 제 사전 검색 비용을 비교합니다. – Matthew

+0

명확히하기 : 참조 객체를 사용하기 위해 컨테이너를 사용하는 경우 컨테이너의 "상자 해제"에 대해 설명합니다. – Matthew

+0

@Matthew PK : 당신은 Ref의 "unboxing"과 Dictionary의 "unboxing"을 가지고 있기 때문에이 함수에서 Ref의 승리가되어야합니다. 그러나 이것은 확실히 마이크로 최적화입니다. –

2

.

성능을 향상 시키려면 ILifeTimeManaged 인터페이스에 RefCount 속성을 추가하고 사전을 사용하는 대신 사용할 수 있습니다. 그러나 나는 당신의 디자인과 목표를 알지 못한다. 그래서 이것이 당신에게 적절한 지 말할 수 없다.

+0

ILifeTimeManaged는 참조 횟수를 저장할 수 없습니다. ILikeTimeManaged 오브젝트는 기본적으로 얼마나 많은 인스턴스가 미해결인지를 추적하고 인스턴스의 생성 또는 삭제를 처리하는 LifeTimeManager에 의해 관리됩니다. – Matthew

+0

확인. Btw, .NET에서 메모리를 관리하는 모든 작업을 수행하기 때문에 실제로 참조를 계산할 필요가 없다는 것을 알았습니까? –

+0

제 경우는 아닙니다. 관리자는 모든 오브젝트의 폐기를 처리하고 오브젝트를 재발행할지 여부를 결정합니다. 당신은 여기에 내 구현에 날 믿어야 해); – Matthew