사전 값 검색 모범 사례


79

저는 최근 Dictionary.TryGetValue(TKey key, out TValue value)에 사전에서 값을 검색하는 더 나은 접근 방식이 무엇 인지 확인 하고 궁금했습니다.

저는 전통적으로 다음을 수행했습니다.

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
     ...

내가 아는 않는 한 거기에있을 수 있습니다.

그냥하는 것이 더 낫습니까?

if (myDict.TryGetValue(somekey, out someVal)
    ...

어느 것이 더 나은 방법입니까? 하나가 다른 것보다 빠릅니까? Try 버전이 자체적으로 try / catch를 '삼키고'논리로 사용하면 속도가 느려질 것이라고 생각합니다.

답변:


84

FindEntry는 한 번만 호출되기 때문에 TryGetValue가 약간 더 빠릅니다.

얼마나 빨리요? 손에있는 데이터 세트에 따라 다릅니다. Contains 메서드를 호출하면 Dictionary는 내부 검색을 수행하여 해당 인덱스를 찾습니다. true를 반환하면 실제 값을 얻기 위해 다른 인덱스 검색이 필요합니다. TryGetValue를 사용하면 인덱스를 한 번만 검색하고 찾은 경우 변수에 값을 할당합니다.

참고 : 실제로 오류가 발생하는 것은 아닙니다.

전화 :

public bool TryGetValue(TKey key, out TValue value)
{
    int index = this.FindEntry(key);
    if (index >= 0)
    {
        value = this.entries[index].value;
        return true;
    }
    value = default(TValue);
    return false;
}

ContainsKey는 다음과 같습니다.

public bool ContainsKey(TKey key)
{
    return (this.FindEntry(key) >= 0);
}

FindEntry는 한 번만 호출되기 때문에 TryGetValue가 약간 더 빠릅니다.
Joe

1
TryGetValue는 큰 사전이있을 때 훨씬 더 빠릅니다
Diadistis

4
이론적으로 (실제로도), 이것은 검색의 예상 (!) 시간이 일정하기 때문에, 즉 사전 크기와 무관하기 때문에 사전의 크기에 의존해서는 안됩니다!
Konrad Rudolph

29

사실 TryGetValue가 더 빠릅니다. 얼마나 빨리요? 손에있는 데이터 세트에 따라 다릅니다. Contains 메서드를 호출하면 Dictionary는 내부 검색을 수행하여 해당 인덱스를 찾습니다. true를 반환하면 실제 값을 얻기 위해 다른 인덱스 검색이 필요합니다. TryGetValue를 사용하면 인덱스를 한 번만 검색하고 찾은 경우 변수에 값을 할당합니다.

편집하다:

알겠습니다. 귀하의 혼란을 이해하므로 자세히 설명하겠습니다.

사례 1 :

if (myDict.Contains(someKey))
     someVal = myDict[someKey];

이 경우 FindEntry에 대한 두 번의 호출이 있습니다. 하나는 키가 있는지 확인하고 다른 하나는 검색합니다.

사례 2 :

myDict.TryGetValue(somekey, out someVal)

이 경우 결과 인덱스가 동일한 메서드에서 실제 검색을 위해 유지되기 때문에 FindKey에 대한 호출이 하나만 있습니다.


동의합니다. TryGetValue를 사용하면 키 조회를 두 번 수행 할 필요가 없습니다. 멀티 스레딩의 경우에도 도움이 될 수 있습니다. 값이 존재하는지 확인하는 시간 사이에 추가 또는 제거되었을 수 있습니다. 이로 인해 "키가 이미 존재 함"또는 "키를 찾을 수 없음"예외가 발생할 수 있습니다.
Brian Rudolph

0

trygetvalue가 다음과 같은 일을한다고 상상합니다.

if(myDict.ReallyOptimisedVersionofContains(someKey))
{ 
  someVal = myDict[someKey];
  return true;
}
return false;

그러니 아무데도 시도 / 잡지 않기를 바랍니다.

정말 편리한 방법이라고 생각합니다. 나는 일반적으로 코드 한두 줄을 절약하기 때문에 그것을 사용합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.