2014-03-27 1 views
0

이미 알고리즘 성능을 크게 향상시킨 HashSet 컬렉션 유형을 사용하고 있습니다. 그것은 바로 myHashSet.Contains(someValue)을 호출 할 때마다 내부 구현이 Equals을 호출하기 직전에 값 유형을 boxing하는 것으로 보입니다.사용자 정의 구조체가있는 HashSet이 Contains 함수를 사용하여 무겁게 할당합니다.

값 유형을 사용할 때 이러한 낭비적인 할당을 피할 수있는 방법이 있습니까?

샘플 코드 : 운이 후

public struct TestStruct { 
    public int a; 
    public int b; 

    public override int GetHashCode() { 
     return a^b; 
    } 

    public override bool Equals(object obj) { 
     if (!(obj is TestStruct)) 
      return false; 
     TestStruct other = (TestStruct)obj; 
     return a == other.a && b == other.b; 
    } 
} 

var hashset = new HashSet<TestStruct>(); 
PopulateSet(hashset); 

// About to go crazy on the allocations... 
if (hashset.Contains(someValue)) { ... } 
// Lots of allocations just happened :(

답변

1

대답은 아래의 증명과 같은 IEquatable<T> 인터페이스를 구현하는 단지처럼 보이는 것 같아요. HashSet<T> (또는 적어도 Mono 구현)은 다른 비교 자 구현을 사용하여 Contains 메서드에 할당되지 않은 접근 방식을 사용합니다.

public struct TestStruct : IEquatable<TestStruct> { 
    ... 

    public bool Equals(TestStruct other) { 
     return a == other.a && b == other.b; 
    } 
} 

// No more pain! 
if (hashset.Contains(someValue)) { ... } 
+1

이것은 MS 구현에서도 마찬가지입니다. 'HashSet'은 가능하면'IEquatable '을 사용하는'EqualityComparer .Default' (사용자 정의 비교기가 제공되지 않았을 때 사용할 수있는 또 다른 옵션입니다)를 사용하고, 그렇지 않은 경우'object' 과부하. – Servy

관련 문제