Section 6.1: 바람직한 GetHashCode 재정의하기
GetHashCode
는 Dictionary<>
와 HashTable
사용에 있어 성능에 지대한 영향을 미치게 된다.
바람직한 GetHashCode 메소드란:
- 균일한 분포 (distribution) 를 가져야 한다.
- 임의의 instance 에 대해, 값으로 반환될 수 있는 확률은 모든 integer 값들이 거의 동일하게 가져야 한다.
- 만약 각각의 instance 들에 대해 동일한 integer 를 반환하게되어 있다면 (예: 언제나 상수 '999' 만을 반환), 성능 저하가 심각하게 일어날 것이다.
- 빠르게 동작해야 한다.
- 이 메소드는 (느린 동작을 특징으로 갖는) 암호화 hash 값을 생성하기 위한 것이 아니다.
- hash 함수가 느려질수록, 사용자의 dictionary 역시 마찬가지로 느려질 것이다.
Equals
가 true 로 평가 (evaluate) 되는 두개의 instance 에 대해서는 동일한 HashCode 를 반환해야 한다.- 그렇지 않은 경우 (예:
GetHashCode
가 난수를 반환한다거나),List
나Dictionary
혹은 그 비슷한 것들에서 요소 검색에 실패할 수 있다.
- 그렇지 않은 경우 (예:
GetHashCode
를 구현하는 좋은 방법 중 하나는 소수 하나를 시작값으로 하여, 각 field 들의 hashcode 를 다른 소수와 곱하여 더해 나가는 것이다:
public override int GetHashCode() {
unchecked // Overflow 가 발생한다해도 wrap 시키면 되므로 문제가 없다
{
int hash = 3049; // 시작 값 (소수)
// 이 위치에 적절한 null 확인 등의 코드가 필요할 것이다
hash = hash * 5039 + field1.GetHashCode();
hash = hash * 883 + field2.GetHashCode();
hash = hash * 9719 + field3.GetHashCode();
return hash;
}
}
Equals
메소드에서 사용되는 field 들만 hash 값 연산에 사용되어야 함에 주의하자.
만약 동일한 타입을 Dictionary
/ HashTable
들에 대하여 각각 다른 방법으로 다루어야 하는 필요가 있는 경우에는, IEqualityComparer
를 사용할 수 있다.
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.
[출처] https://books.goalkicker.com/CSharpBook/
반응형
'번역 > C# Notes for Professionals' 카테고리의 다른 글
6.3: 사용자 정의 타입에 대해 Equals 와 GetHashCode 재정의하기 (0) | 2020.11.25 |
---|---|
6.2: Equals 의 기본 동작 (0) | 2020.11.23 |
5.1: C# 에서의 동일성 (equally) 종류와 동일 연산자 (0) | 2020.11.19 |
4.3: If-Else If-Else 문 (0) | 2020.11.17 |
4.2: If 문의 조건식 (0) | 2020.11.17 |