Development Tip

IEnumerable Count ()와 길이의 차이점

yourdevel 2020. 12. 11. 20:24
반응형

IEnumerable Count ()와 길이의 차이점


주요 차이점은 무엇입니까 IEnumerable Count()와는 Length?


Count on을 호출 IEnumerable<T>하면 .NET의 확장 메서드 Count참조한다고 가정합니다 System.Linq.Enumerable. Length는 메서드가 IEnumerable<T>아니라 .Net의 배열 유형에 대한 속성입니다 int[].

차이점은 성능입니다. Length속성은 O (1) 동작이 보장된다. Count확장 메서드 의 복잡성은 개체의 런타임 유형에 따라 다릅니다. 속성을 ICollection<T>통해 O (1) 길이 조회를 지원하는 여러 유형으로 캐스트하려고 시도 Count합니다. 사용 가능한 항목이 없으면 모든 항목을 열거하고 복잡성이 O (N) 인 항목을 계산합니다.

예를 들면

int[] list = CreateSomeList();
Console.WriteLine(list.Length);  // O(1)
IEnumerable<int> e1 = list;
Console.WriteLine(e1.Count()); // O(1) 
IEnumerable<int> e2 = list.Where(x => x <> 42);
Console.WriteLine(e2.Count()); // O(N)

이 값 e2은 O (1) 계산을 지원하지 않는 C # 반복기로 구현되므로 메서드 Count는 전체 컬렉션을 열거하여 컬렉션의 길이를 결정해야합니다.


Jon Skeet 의 의견에 약간의 추가 .

다음은 Count()확장 메서드 의 소스 코드입니다 .

.NET 3 :

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    ICollection<TSource> is2 = source as ICollection<TSource>;
    if (is2 != null)
    {
        return is2.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num++;
        }
    }
    return num;
}

.NET 4 :

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    ICollection<TSource> is2 = source as ICollection<TSource>;
    if (is2 != null)
    {
        return is2.Count;
    }
    ICollection is3 = source as ICollection;
    if (is3 != null)
    {
        return is3.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num++;
        }
    }
    return num;
}

  • 길이는 고정 된 속성 (예 : 1 차원 배열 또는 문자열)입니다. 따라서 카운트 연산이 필요하지 않습니다 (다차원 배열에는 모든 차원이 곱해진 크기가 있음). 여기서 O (1) 연산은 검색 시간이 얼마나 많은 요소가 있더라도 항상 동일하다는 것을 의미합니다. 선형 검색은 (반대) O (n)입니다.

  • The Count property on ICollections (List and List<T>, for example) can change, so it has either to be updated on Add/Remove operations, or when Count is requested after the Collection has changed. Depends on the implementation of the object.

  • The Count() method of LINQ basically iterates EVERY TIME it is called (except when the object is an ICollection type, then the ICollection.Count property is requested).

Note that IEnumerables are often not already defined object collections (like lists, arrays, hashtables etc.), but link to background operations, which generate results whenever they are requested (called deferred execution).

Typically, you have an SQL like LINQ statement like this (the typical application of deferred execution):

IEnumerable<Person> deptLeaders = 
   from p in persons
   join d in departments
      on p.ID equals d.LeaderID
   orderby p.LastName, p.FirstName
   select p;

Then, there's code like this:

if (deptLeaders.Count() > 0)
{
   ReportNumberOfDeptLeaders(deptLeaders.Count());
   if (deptLeaders.Count() > 20)
      WarnTooManyDepartmentLeaders(deptLeaders.Count());
}

So, when a warning for too many Department Leaders is issued, .NET goes FOUR TIMES through the persons, checks them against the department leaders, sorts them by name and then counts the result objects.

And this is only when persons and departments are preset value collections, not queries themselves.

참고URL : https://stackoverflow.com/questions/2521592/difference-between-ienumerable-count-and-length

반응형