foreach 루프에있는 개체의 List 속성 채우기

c# dapper

문제

객체의리스트를 채우는 것이 내가 실행할 때보 다 빨리 할 수 ​​있는지 궁금합니다. 나는 CABCodes- & CABDetails-lists에 Dapper를 사용하는 간단한 쿼리를 .ToList ();로 채 웁니다.

그래서 두리스트는 모두 메모리에 있지만, foreach 연산은 20 초 정도 걸립니다.

CABCodes : ~ 10,000 개체

CABDetails : ~ 60,000 개 개체

List<CABCode> CABCodes = new List<CABCode>();
List<CABDetail> CABDetails = new List<CABDetail>();

public class CABCode {
    public int Sequence { get; set; }
    public string Code { get; set; }
    public int Group { get; set; }
    public List<CABDetail> Details { get; set; }
}
public class CABDetail {
    public int CABSequence { get; set; }
    public int Proptype { get; set; }
    public string Propvalue { get; set; }
}

foreach (var c in this.CABCodes) {
    c.Details = this.CABDetails.Where(x => x.CABSequence == c.Sequence).ToList();
}

이것을 달성하는 훨씬 더 효율적인 방법이 있습니까?

수락 된 답변

O (M * N) 알고리즘 시간이 있습니다. 다음 코드는 O (M + N)을 만듭니다.

var cabDetailsBySequence = CABDetails.ToLookup(d=>d.CABSequence);

foreach (var c in this.CABCodes) {
    c.Details = cabDetailsBySequence[c.Sequence].ToList();
}

업데이트 : 100 개의 시퀀스 코드가있는 110ms에서 작동하는지 확인했습니다.

다음은 테스트 설정입니다.

CABCodes = Enumerable.Range(0, 10000).Select(i=>new CABCode{Sequence = i%100}).ToList();
CABDetails = Enumerable.Range(0, 60000).Select(i=>new CABDetail{CABSequence = i%100}).ToList();

업데이트 2 : 그리고 다른 CABCode 인스턴스에서 같은 목록에 대한 참조가있을지라도 더 빠르게 (20 회 aprox) 만들 수 있으며 병렬로 수행하는 경우 더 빨리 수행 할 수도 있습니다. 이렇게하면 내 8 코어 시스템에서 1 밀리 초 미만으로 실행됩니다.

var cabDetailListsBySequence = cabDetailsBySequence.ToDictionary(i=>i.Key, i=>i.ToList());

//  foreach (var c in this.CABCodes) {
//      c.Details = cabDetailListsBySequence[c.Sequence];
//  }   

this.CABCodes.AsParallel().ForAll(c=>c.Details = cabDetailListsBySequence[c.Sequence]);

인기 답변

Linq는 if / else 문으로 자신의 루프를 작성하는 것보다 항상 빠르지는 않습니다. 두 번째로, ToList ()는 List의 새 인스턴스를 만들고 이는 성능을 저하시킵니다.

이 코드의 성능은 어떻습니까?

foreach (var c in this.CABCodes) 
{
  var detailList = new List<CABDetail>();
  foreach(var d in CAPDetails)
  {
    if (d.CABSquence == c.Sequence)
    {
      detailList.Add(d);
    }
  }
  c.Details = detailList;
}

코드에서 실수를 한 것 같습니다. 왜냐하면 내가 직접 작성한 코드이기 때문입니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow