[C#] Lookup ()과 Dictionary (Of list ())의 차이점

어떤 데이터 구조가 가장 효율적인지, 언제 어디에서 어떤 데이터 구조를 사용 해야하는지 내 머리를 감싸려고합니다.

이제 구조를 충분히 이해하지 못했을 수도 있지만 어떻게 ILookup(of key, ...)다른 Dictionary(of key, list(of ...))가요?

또한 어디에서 사용하고 싶고 ILookup프로그램 속도 / 메모리 / 데이터 액세스 등의 측면에서 더 효율적입니까?



답변

두 가지 중요한 차이점 :

  • Lookup불변입니다. Yay 🙂 (적어도 구체적인 Lookup클래스는 불변이고 ILookup인터페이스는 변경 멤버를 제공하지 않습니다. 물론 다른 변경 가능한 구현 이 있을 수 있습니다.)
  • 조회에없는 키를 조회하면 KeyNotFoundException. 대신 빈 시퀀스가 ​​다시 나타납니다 . 따라서 TryGetValueAFAICR 은 없습니다 .

그것들은 효율성면에서 동등 할 것 Dictionary<TKey, GroupingImplementation<TValue>>입니다. 예를 들어, 룩업은 배후에서 잘 사용할 수 있습니다 . 요구 사항에 따라 둘 중에서 선택하십시오. 개인적으로 조회는 일반적으로 Dictionary<TKey, List<TValue>>위의 처음 두 지점으로 인해 보다 낫습니다 .

구현 세부 사항으로, 구체적인 구현은 IGrouping<,>값 구현 IList<TValue>에 사용됩니다 Count(). ElementAt()즉와 함께 사용하는 것이 효율적임을 의미합니다 .


답변

아무도 실제로 가장 큰 차이점을 언급하지 않았다는 점에 흥미가 있습니다 ( MSDN 에서 직접 가져옴 )

조회는 사전과 유사합니다. 차이점은 Dictionary는 키를 단일 값에 매핑하고 Lookup은 키를 값 모음에 매핑한다는 것입니다.


답변

a Dictionary<Key, List<Value>>Lookup<Key, Value>논리적으로 데이터를 유사한 방식으로 구성 할 수 있으며 둘 다 동일한 순서로 효율성을 갖습니다. 주요 차이점은Lookup 변경 불가능합니다. Add()메서드와 퍼블릭 생성자 가 없습니다 (존이 언급했듯이 예외없이 존재하지 않는 키를 쿼리하고 그룹화의 일부로 키를 가질 수 있음).

어느 것을 사용 하느냐에 따라 실제로 어떻게 사용 하느냐에 달려 있습니다. 지속적으로 수정되는 여러 값에 대한 키 맵을 유지 관리하는 경우Dictionary<Key, List<Value>> 는 변경 가능하므로 더 좋습니다.

그러나 일련의 데이터가 있고 키로 구성된 데이터에 대한 읽기 전용보기 만 원하는 경우 조회를 구성하는 것이 매우 쉽고 읽기 전용 스냅 샷을 제공합니다.


답변

ILookup<K,V>a와 a 의 주요 차이점은 Dictionary<K, List<V>>사전을 변경할 수 있다는 것입니다. 키를 추가하거나 제거 할 수 있으며 조회 한 목록에서 항목을 추가하거나 제거 할 수도 있습니다. 은 ILookup이다 불변 및 생성 후 수정할 수 없습니다.

두 메커니즘의 기본 구현은 동일하거나 유사하므로 검색 속도와 메모리 풋 프린트가 거의 동일합니다.


답변

아직 언급되지 않은 또 다른 차이점은 Lookup () 이 null 키를 지원 한다는 것입니다 .

Lookup 클래스는 ILookup 인터페이스를 구현합니다. 조회는 여러 값이 동일한 키에 맵핑 될 수 있고 널 키가 지원된다는 점을 제외하면 사전과 매우 유사합니다.


답변

예외가 옵션이 아닌 경우 조회로 이동하십시오.

a만큼 효율적인 구조를 얻으려고 Dictionary하지만 입력에 중복 키가 없는지 확실하지 않으면 Lookup더 안전합니다.

다른 답변에서 언급했듯이 null 키도 지원하며 임의의 데이터로 쿼리 할 때 항상 유효한 결과를 반환하므로 알 수없는 입력에 더 탄력적 인 것으로 보입니다 (예외보다 예외가 발생하기 쉽습니다).

그리고 System.Linq.Enumerable.ToDictionary함수와 비교하면 특히 그렇습니다 .

// won't throw
new[] { 1, 1 }.ToLookup(x => x);

// System.ArgumentException: An item with the same key has already been added.
new[] { 1, 1 }.ToDictionary(x => x);

대안은 foreach루프 내에서 자신의 중복 키 관리 코드를 작성하는 것 입니다.

성능 고려 사항, 사전 : 확실한 승자

목록이 필요하지 않고 많은 수의 항목을 관리하려는 경우 Dictionary(또는 사용자 정의 된 맞춤 구조) 더 효율적일 수 있습니다.

        Stopwatch stopwatch = new Stopwatch();
        var list = new List<string>();
        for (int i = 0; i < 5000000; ++i)
        {
            list.Add(i.ToString());
        }
        stopwatch.Start();
        var lookup = list.ToLookup(x => x);
        stopwatch.Stop();
        Console.WriteLine("Creation: " + stopwatch.Elapsed);

        // ... Same but for ToDictionary
        var lookup = list.ToDictionary(x => x);
        // ...

으로 Lookup는 (항목의 거대한 수의 3 배 느린 정도) 느린 사전보다, 각 키에 대한 항목의 목록을 유지해야한다

조회 속도 : 생성 : 00 : 00 : 01.5760444

사전 속도 : 제작 : 00 : 00 : 00.4418833


답변