문제

안녕하세요, 다음 두 가지 방법을 가정해 보겠습니다.

private List<IObjectProvider> GetProviderForType(Type type)
        {
            List<IObjectProvider> returnValue = new List<IObjectProvider>();

            foreach (KeyValuePair<Type, IObjectProvider> provider in _objectProviders)
            {
                if ((provider.Key.IsAssignableFrom(type) ||
                    type.IsAssignableFrom(provider.Key)) &&
                    provider.Value.SupportsType(type))
                {
                    returnValue.Add(provider.Value);
                }
            }
            return returnValue;
        }

private IEnumerable<IObjectProvider> GetProviderForType1(Type type)
        {
            foreach (KeyValuePair<Type, IObjectProvider> provider in _objectProviders)
                if ((provider.Key.IsAssignableFrom(type) ||
                    type.IsAssignableFrom(provider.Key)) &&
                    provider.Value.SupportsType(type))

                    yield return provider.Value;              
        }

어느 것이 더 빠르나요?첫 번째 방법을 보면 List에 메모리가 할당되어 있는데 제 생각에는 필요하지 않은 것 같습니다.그만큼 IEnumerable 나에게는 방법이 더 빠른 것 같다.

예를 들어, 전화를 걸었다고 가정해 보겠습니다.

int a = GetProviderForType(myType).Count;
int b = GetProviderForType1(myType).Count();

이제 또 다른 문제는 위의 두 가지 사이에 성능 차이가 있습니까?

어떻게 생각하나요?

도움이 되었습니까?

해결책

이 특별한 경우에는 IEnumerable<T> 양식을 작성하는 것이 더 효율적일 것입니다. 오직 수를 알아야 합니다.필요하지 않은 경우 데이터를 저장하고 버퍼 크기를 조정하는 등의 작업은 의미가 없습니다.

어떤 이유로든 결과를 다시 사용해야 하는 경우 List<T> 형태가 더 효율적일 것입니다.

두 가지 모두 Count() 확장 방법과 Count 부동산은 효율적일 것입니다 List<T> 구현으로 Count() 대상 시퀀스가 ​​구현되는지 확인합니다. ICollection<T> 그리고 Count 그렇다면 재산.

균등해야 하는 또 다른 옵션 효율적이지만 (비록 단지) Count 대리인이 필요합니다.

private int GetProviderCount(Type type)
{
  return _objectProviders.Count(provider =>
      (provider.Key.IsAssignableFrom(type) 
       || type.IsAssignableFrom(provider.Key))
      && provider.Value.SupportsType(type));
}

그러면 다음과 같은 추가 수준의 간접 참조가 방지됩니다. Where 그리고 Select 조항.

(Marc가 말했듯이, 적은 양의 데이터의 경우 성능 차이는 어쨌든 무시할 수 있을 것입니다.)

다른 팁

이와 같은 질문에 대한 정확한 답변은 많은 요인에 따라 다를 수 있으며 CLR이 진화함에 따라 더 변화 될 수 있습니다. 확실하게하는 유일한 방법은 그것을 측정하는 것입니다. 그리고 차이가 작전에 비해 작은 경우, 이것이 가장 읽기 쉬운 유지 관리 가능한 방법을 선택해야한다는 것을 명심하십시오.

그리고 그 메모에서, 당신은 또한 시도하고 싶을 수도 있습니다.

private IEnumerable<IObjectProvider> GetProviderForType1(Type type)
{
    return _objectProviders.Where(provider => 
                  provider.Key.IsAssignableFrom(type) ||
                  type.IsAssignableFrom(provider.Key)) &&
                  provider.Value.SupportsType(type))
                           .Select(p => p.Value);
}

당신은 또한 돌아와서 많은 유연성을 줄 수 있습니다. IEnumerable<T> 그리고 사용합니다 ToList 확장 메소드 결과를 목록에 "스냅 샷"하려면. 이렇게하면 여러 번 검사 해야하는 경우 목록을 생성하기위한 코드의 반복적 인 평가를 피할 수 있습니다.

이 질문의 중요한 부분은 "데이터가 얼마나 큽니까?"입니다. 얼마나 많은 행 ...

소량의 데이터의 경우 목록이 괜찮습니다. 큰 목록을 할당하는 데 무시할만한 시간이 걸리며 여러 번 크기를 조정하지 않습니다 (미리 미리 얼마나 큰지 알 수 있다면).

그러나 이것은 막대한 데이터 볼륨으로 확장되지 않습니다. 귀하의 공급자가 수천 개의 인터페이스를 지원할 가능성은 거의 없으므로 필요한 이 모델로 이동하려면 - 그러나 그것은 크게 아프지 않을 것입니다.

물론 LINQ도 사용할 수 있습니다.

return from provider in _objectProviders
       where provider.Key.IsAssignableFrom(type) ...
       select provider.Value;

이것은 또한 연기입니다 yield 표지 아래에 접근하는 ...

ienumerable과 ilist의 주요 차이점 :

ienumerable : movenext를 구현하고, 재설정하고, 현재 메소드를 가져오고, Ienumerator 유형을 반환하여 레코드를 반복합니다.

ILIST : Ienumerable 인터페이스를 노출시켜 색인을 통해 액세스 할 수있는 비 영진 객체 모음이므로 Ienumerable+icollection (데이터 조작) 및 추가, 제거, 삽입 (특정 색인)이 구현 한 유용한 방법입니다. 일리스트.

내 의견으로는 코드를 살펴본 후 ienumerable이 더 효율적이지만 데이터를 사용하여 약간의 조작을하고 싶다면 데이터를 반복하려면 ienumerable이 바람직합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top